H2 DB - Column must be in Group By list - java

i am using H2-DB to access static databases...
i have a table which looks like:
COUNTRY STATE CITY LAT LNG COUNTRYID STATEID CITYID
"Germany" "Berlin" "" 1.23 1.23 1 1 0
"Germany" "München" "" 1.23 1.23 1 2 0
"USA" "Alabama" "Auburn" 1.23 1.23 2 1 1
"USA" "Alabama" "Birmingham" 1.23 1.23 2 1 2
"USA" "Alaska" "Anchorage" 1.23 1.23 2 2 1
"USA" "Alaska" "Cordova" 1.23 1.23 2 2 2
its a huge list with lots of countries, most of them just have Country and State (like Germany here, whereas State's are Cities), a few also have a City (like USA here)...
the problem is now, when i query
SELECT * FROM MyTable WHERE COUNTRY = 'Germany' group by STATE order by STATE
to get a sorted list of the states (or cities), i get an error saying
Field CITY must be in the GROUP BY list
if the row has a city, i need the whole row, otherwise i would only need the State column, but i can just know after having queried it, wether it uses the city column or not, so i have to query "*" instead of "STATE"
the query should be okay, or? On MySql it is properly working... so whats the problem here?
Found this if it helps: http://www.h2database.com/javadoc/org/h2/constant/ErrorCode.html#c90016
Metin

MySQL is broken in regards to this. It allows columns in the GROUP BY that are neither in the group by nor arguments to aggregation functions. In fact, the documentation warns against using this extension.
So you can do:
SELECT state
FROM DIYANET
WHERE COUNTRY = 'Germany'
GROUP BY STATE
ORDER BY STATE;
Or something like this:
SELECT state, min(city), min(lat), . . .
FROM DIYANET
WHERE COUNTRY = 'Germany'
GROUP BY STATE
ORDER BY STATE;
But SELECT * is not allowed and doesn't really make sense.

Related

How to match number "start with" through query sqlite

Is there any way to match the query, for example, I want to search my number against the rules (table name) through query.
I want to match the number which starts with "333" rules .........
1)3322323
Here is my query
SELECT * FROM demo where rules like '33322323';
I want above query return true. because it matches with my rule.
Below is my table.
id | rules
...............
1 | 333
2 | 22
3 | 442
I have sample data 1) 33331235, 2) 2354545 3) 4424545454 4) 22343434
Case 1 (matching data 1) 33331235)
Suppose I want to check my 33331235 with my rules table so my sample data match with my
row 1 which is 333, because of my data start with 333..... it should return true because of it matched.
Case 2 (matching data 2) 2354545)
Suppose I want to check my 2354545 with my rules table so my sample data does not match with my
Any row because my no rule applies on it..... it should return true because of it matched.
Case 3 (matching data 1) 4424545454)
Suppose I want to check my 4424545454 with my rules table so my sample data match with my
row 1 which is 442, because of my data start with 442..... it should return true because of it matched.
Solved.
I solved this with the help of Forpas I used this query to match number start with
SELECT * FROM demo where '333434334 like rules ||'%';
The number at the end of the string when I use this query.
SELECT * FROM demo where '333434334' like '%' || rules;
The number anywhere in the string then I use this query.
SELECT * FROM demo where '333434334' like '%' || rules ||'%';
You need to use the operator LIKE.
You have tagged your question with both MySQL and SQLite.
For MySQL:
SELECT * FROM demo where '33322323' like concat(rules, '%');
For SQLite:
SELECT * FROM demo where '33322323' like rules || '%';
The above code will return all rows where the rules column value is the starting chars of 33322323.

FOREACH in cypher - neo4j

I am very new to CYPHER QUERY LANGUAGE AND i am working on relationships between nodes.
I have a CSV file of table containing multiple columns and 1000 rows.
Template of my table is :
cdrType ANUMBER BNUMBER DUARTION
2 123 456 10
2 890 456 5
2 123 666 2
2 123 709 7
2 345 789 20
I have used these commands to create nodes and property keys.
LOAD CSV WITH HEADERS FROM "file:///2.csv" AS ROW
CREATE (:ANUMBER {aNumber:ROW.aNumber} ),
CREATE (:BNUMBER {bNumber:ROW.bNumber} )
Now I need to create relation between all rows in the table and I think FOREACH loop is best in my case. I created this query but it gives me an error. Query is :
MATCH (a:ANUMBER),(b:BNUMBER)
FOREACH(i in RANGE(0, length(ANUMBER)) |
CREATE UNIQUE (ANUMBER[i])-[s:CALLED]->(BNUMBER[i]))
and the error is :
Invalid input '[': expected an identifier character, whitespace,
NodeLabel, a property map, ')' or a relationship pattern (line 3,
column 29 (offset: 100)) " CREATE UNIQUE
(a:ANUMBER[i])-[s:CALLED]->(b:BNUMBER[i]))"
I need relation for every row. like in my case. 123 - called -> 456 , 890 - called -> 456. So I need visual representation of this calling data that which number called which one. For this I need to create relation between all rows.
any one have idea how to solve this ?
What about :
LOAD CSV WITH HEADERS FROM "file:///2.csv" AS ROW
CREATE (a:ANUMBER {aNumber:ROW.aNumber} )
CREATE (b:BNUMBER {bNumber:ROW.bNumber} )
MERGE (a)-[:CALLED]->(b);
It's not more complex than that i.m.o.
Hope this helps !
Regards,
Tom

Symptoms and its disease database design

Im working with android health application which will display human body parts such as head, chest etc.. For now I have three tables such as symptoms, diseases and symptom_disease table which will link those two table. If user select symptom such as dizziness, syncope, asthenia and others, then it will display hypertensive disease. But it will have problem when user select only one symptoms let say dizziness, it will also display the same disease. How do i differentiate this things? and how to implement it.
This is my symptom table
s_id | s_name | s_part
1 |dizziness | Head
2 |syncope | Head
3 |asthenia | Head
Disease table
d_id | d_name | d_desc
1 |hypertensive disease| ....
Symptom_disease table
s_id | d_id
1 | 1
2 | 1
3 | 1
I use this query to get the disease
SELECT d.d_name, d.d_desc, s.symp_name
FROM symtoms s
LEFT JOIN symptom_disease sd ON sd.sid = s.sid
LEFT JOIN diseases d ON d.did = sd.did
WHERE s.sid IN (1,2,3) GROUP BY d.d_name
The problem here is when user select only one disease, I dont want it show the disease because one symptoms does not show that the user is ill. So, I need a suggestion on how to implement this. I have see a solution which require me to add rank/weight inside symptom_disease table. But I dont know how to implement this method. Thanks in advance.
Here's a basic approach to use something like a probability column to determine the likelihood of a particular disease.
For diseases table:
1 Flu
2 Lyme
For symptoms table:
1 Muscle Aches
2 Headache
3 Fatigue
4 Fever
5 Vomiting
6 Tick Bite
For disease_symptom table:
s_id d_id probability
1 1 0.2
2 1 0.2
3 1 0.2
4 1 0.2
5 1 0.2
1 2 0.1
2 2 0.1
3 2 0.1
4 2 0.1
6 2 0.6
So if a patient says that have symptoms 2, 4, and 5, then
select d_name, sum(probability)
from disease, disease_symptom
where disease.d_id = disease_symptom.d_id
and s_id in (2, 4, 5)
group by d_name
order by sum(probability) desc
is
Flu 0.6
Lyme 0.2
so Flu is the most likely.
But if the patient has symptoms 2, 4, and 6, then
select d_name, sum(probability)
from disease, disease_symptom
where disease.d_id = disease_symptom.d_id
and s_id in (2, 4, 6)
group by d_name
order by sum(probability) desc
is
Lyme 0.8
Flue 0.4
so Lyme disease is mostly likely.
This may not be the most elegant way of doing it, but it should work, assuming you're using MySql:
select *
from
(
select d.d_name, d.d_desc, GROUP_CONCAT(sd.s_id SEPARATOR ',') s_ids
from Diseases d , Symptom_disease sd
where sd.d_id = d.d_id
group by d.d_name, d.d_desc
order by sd.s_id
) as t
where t.s_ids = '1,2,3'
;
You need to make sure you concatenate all the sympton ids in ascending order in the where clause of the outer select ( where t.s_ids = '1,2,3'), and it should give you only the diseases whose symptons match exactly the ones your users selected.

Hibernate criteria to fetch the records?

I have below records in table.
col1 col2 col3
------------------------
1 Abc IN
2 DEF CA
3 Xyz IN
4 Cae CA
5 Pty IN
6 Zwe DE
7 Zwf US
Here User sends an Input like IN or CA or DE etc. User input has to be mapped against col3. Now I need to query all the records from the table but the records matching the user input (IN or CA or DE) should appear first in the list then all other records should appear. How can I do it using hibernate criteria?
I need the results in below the order if user sends IN as an input.
1 Abc IN
5 Pty IN
3 Xyz IN
2 DEF CA
4 Cae CA
6 Zwe DE
7 Zwf US
You could try to use ORDER BY CASE construct:
order by case when <your entity>.col3 = :parameter then '0' else '1' end asc
There are two ways to solve this problem:
1. Create two queries one with equal to another with not equal to and all results for both in single list.
2. If you don't want to query database twice then you have to write algo in java that will remove elements for your input from list and add it another list and after iteration add remaining list at the end.
try the case ... when statements:
select *, ( case when col3=:input then '0' | col3 else col3 end) as sorter from table order by sorter asc
not sure, if it works, but if it does it would be exactly what you want

PostgreSQL. Search for a value through a list of attributes with a specific id

I need to make search for an object by specific attributes. I have a table item_attribute:
item_attribute             item_attribute_type_fk            item_fk              value_text
1 1 1 bbbb
2 2 1 450-240-310
3 3 1 800x250
4 4 1 2,2
5 1 2 HBO
etc
I've tried this:
SELECT item,name,sale_price,producer,producer_code,store_price,I.type_name
FROM ((item INNER JOIN unit_type ON unit_type_fk=unit_type)
INNER JOIN item_store ON item=item_fk)AS I
INNER JOIN item_attribute AS A ON I.item=A.item_fk
WHERE store_price BETWEEN 200.0 AND 300.0
AND (UPPER(value_text) LIKE UPPER('%b%') AND item_attribute_type_fk=1)
AND (UPPER(value_text) LIKE UPPER('%2%') AND item_attribute_type_fk=4)
GROUP BY item,I.type_name ORDER BY item
Result should be row, where item_fk = 1, but in reality select returns zero rows. If I change AND to OR between attributes that will result in several rows, which is not exactly what I want, because search need to return only that object, that has all attributes, that user typed in in search field. How should I change code, that it will look for a value only through attributes with specific item_attribute_type_fk and return row with object, that has all that attributes?
You appear to be using an EAV-like schema.
To query multiple values in EAV you have to join the same table multiple times. e.g.
SELECT item,name,sale_price,producer,producer_code,store_price,I.type_name
FROM
item
INNER JOIN unit_type ON unit_type_fk=unit_type
INNER JOIN item_store ON item=item_fk)AS I
INNER JOIN item_attribute AS a1 ON I.item = a1.item_fk
INNER JOIN item_attribute AS a2 ON I.item = a2.item_fk -- note second join
WHERE store_price BETWEEN 200.0 AND 300.0
AND (UPPER(a1.value_text) LIKE UPPER('%b%') AND a1.item_attribute_type_fk=1)
AND (UPPER(a2.value_text) LIKE UPPER('%2%') AND a2.item_attribute_type_fk=4)
GROUP BY item, I.type_name
ORDER BY item
Consider transitioning to using json or hstore for your attributes. It's lots less painful to query.

Categories