JOOQ/SQL How to select min date based on foreign key - java

I have a table called Foo which contains 3 columns, (id, time, barId) and I would like to select all fields from Foo where the time (stored as a timestamp) is the lowest one in a group of barId. For example if I had
Id, time, barId
1, 10am, 1
2, 11am, 1
3, 10am, 2
4, 9am, 2
I would expect to receive back rows 1 and 4.
Currently I am using
.select(FOO.ID, FOO.TIME.min, FOO.BAR_ID)
.from(FOO)
.where()
.groupBy(FOO.BAR_ID)
.fetchInto(Foo.class);
And I am receiving an error stating column "foo.id" must appear in the GROUP BY clause or be used in an aggregate function

The issue I had was that I was not grouping by the rows I was selecting.
The working code is
.select(FOO.ID, FOO.TIME.min, FOO.BAR_ID)
.from(FOO)
.where()
.groupBy(FOO.ID, FOO.TIME, FOO.BAR_ID)
.fetchInto(Foo.class);

Related

How do I execute local/remote sync commands sequentially? Android Architecture, Retrofit and Room database

I have a few tables I need to sync between my remote database and my local room database.
Basically, if remote users add to the remote tables and local users add to the local tables, there are now duplicate ids representing different table entries.
When the user hits the sync button, the ids in the local tables are changed so when the remote tables are inserted, no duplicate ids occur.
I've been trying to do this:
syncItemsOfType(User.class);
syncItemsOfType(Car.class);
syncItemsOfType(Key.class);
But each command executes on it's own background thread and takes a bit of time to fetch the remote data, fetch the local data and then merge the two. As a result, some tables are changing their ids before the OwnerIds have been updated. As a result, the OwnerIds are pointing to the wrong entry.
I'd like to create a single background thread and execute the 3 sync commands sequentially on that thread.
So syncItemsOfType(User.class); would start a few threads of its own to gather the data, but don't execute syncItemsOfType(Car.class); until the user sync has completed.
Could RxJava be helpful? I am only familiar with the bare basics of it...
Here's a concrete example if it helps:
Say a user can own multiple cars. So each car_table entry has a userOwnerId to link that car to its user.
Each car can have multiple sets of keys. So each key has a carOwnerId to link that key to its car.
Local Database:
user_table(id, name)
0, Joe
1, Amy
car_table(id, name, userOwnerId)
0, Mustang1, 0
1, Chevy1, 0
2, Chevy2, 1
key_table(id, carId)
0, 0
1, 1
2, 1
3, 2
Remote Database:
user_table(id, name)
0, Billy
car_table(id, name, userOwnerId)
0, Ford1, 0
keys_table(id, carId)
0, 0
Final synced database:
user_table(id, name)
0, Billy
1, Joe
2, Amy
car_table(id, name, userOwnerId)
0, Ford1, 0
1, Mustang1, 1
2, Chevy1, 1
3, Chevy2, 2
keys_table(id, carId)
0, 0
1, 1
2, 2
3, 2
4, 3

How to update multiple rows using a single query with a mutable colletion

I want to update rows on a table which contains the following colums:
`parameter_name`(PRIMARY KEY),
`option_order`,
`value`.
I have a collection called parameterColletion which contains "parameterNames", "optionOrders" and "values". This collection does not have a fixed value, it can receive the quantity of parameters you want to.
Imagine I have 5 parameters inside my collection (I could have 28, or 10204 too) and I am trying to update the rows of the database using the next query. Example of query:
UPDATE insight_app_parameter_option
SET option_order IN (1,2,3,4,5), value IN ('a','b','c','d','e')
WHERE parameter_name IN ('name1', 'name2', 'name3', 'name4', 'name5')
But this isn't doing the job, instead it gives back an error which says You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IN (1,2,3,4,5), value IN ('a','b','c','d','e') WHERE parameter_name IN ('name1'' at line 2
1,2,3,4,5 -> Represent the option orders inside parameterCollection.
'a','b','c','d','e' -> Represent the values inside parameterCollection.
'name1', 'name2', 'name3', 'name4', 'name5' -> Represent the names inside parameterCollection.
I know how to update each parameter by separate but i would like to do it all together. Here are some links I visited where people asked the same question but they used a fixed colletion of objects, not a mutable one.
MySQL - UPDATE multiple rows with different values in one query
Multiple rows update into a single query
SQL - Update multiple records in one query
That's not possible with MySQL. The error you are receiving is a syntax error. You are not able to set multiple values at once. This is the correct syntax to a UPDATE statement: (ref)
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET assignment_list
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
value:
{expr | DEFAULT}
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...
You need to create separate UPDATEs for each row. I suggest executing all in a single transaction, if its the case.
The correct syntax for your example is:
UPDATE insight_app_parameter_option
SET option_order = 1, value = 'a'
WHERE parameter_name = 'name1';
UPDATE insight_app_parameter_option
SET option_order = 2, value = 'b'
WHERE parameter_name = 'name2';
UPDATE insight_app_parameter_option
SET option_order = 3, value = 'c'
WHERE parameter_name = 'name3';
...

ORMLite groupByRaw and groupBy issue on android SQLite db

I have a SQLite table content with following columns:
-----------------------------------------------
|id|book_name|chapter_nr|verse_nr|word_nr|word|
-----------------------------------------------
the sql query
select count(*) from content where book_name = 'John'
group by book_name, chapter_nr
in DB Browser returns 21 rows (which is the count of chapters)
the equivalent with ORMLite android:
long count = getHelper().getWordDao().queryBuilder()
.groupByRaw("book_name, chapter_nr")
.where()
.eq("book_name", book_name)
.countOf();
returns 828 rows (which is the count of verse numbers)
as far as I know the above code is translated to:
select count(*) from content
where book_name = 'John'
group by book_name, chapter_nr
result of this in DB Browser:
| count(*)
------------
1 | 828
2 | 430
3 | 653
...
21| 542
---------
21 Rows returned from: select count(*)...
so it seems to me that ORMLite returns the first row of the query as the result of countOf().
I've searched stackoverflow and google a lot. I found this question (and more interestingly the answer)
You can also count the number of rows in a custom query by calling the > countOf() method on the Where or QueryBuilder object.
// count the number of lines in this custom query
int numRows = dao.queryBuilder().where().eq("name", "Joe Smith").countOf();
this is (correct me if I'm wrong) exactly what I'm doing, but somehow I just get the wrong number of rows.
So... either I'm doing something wrong here or countOf() is not working the way it is supposed to.
Note: It's the same with groupBy instead of groupByRaw (according to ORMLite documentation joining groupBy's should work)
...
.groupBy("book_name")
.groupBy("chapter_nr")
.where(...)
.countOf()
EDIT: getWordDao returns from class Word:
#DatabaseTable(tableName = "content")
public class Word { ... }
returns 828 rows (which is the count of verse numbers)
This seems to be a limitation of the QueryBuilder.countOf() mechanism. It is expecting a single value and does not understand the addition of GROUP BY to the count query. You can tell that it doesn't because that method returns a single long.
If you want to extract the counts for each of the groups it looks like you will need to do a raw query check out the docs.

SQL / Hibernate Criteria - Group By Trouble

I'm having some trouble here to create an appropriate SQL query. Any help will be much appreciated!
Some background:
I have the following entities
Equipment
id
nickname
owner_indicator
{...}
EquipmentGroup_Equipment
equipment_id
equipment_group_id
EquipmentGroup
id
name
description
I need to do a SQL / JPA Hibernate query that returns me:
EquipmentGroup.name, EquipmentGroup.description, Equipment.owner_indicator
And this will be grouped by EquipmentGroup.id, so if I have 10 equipments inside the group it will return information grouped by the EquipmentGroup.
The thing is, when I have for example more than one owner_indicator inside a EquipmentGroup it will return 2 rows. This is SQL 101. But i must return only one line with a blank text instead of the Owner Indicator.
What is the easiest way to do this ? I'd be glad to have the answer in SQL, but much more than glad to have it in Criteria JPA, heh.
If it does matter, I'm using Oracle 12c.
Thanks!
EDIT
As requested, here is some data:
Equipment
id nickname owner_indicator
1 EQP01 'V'
2 EQP02 'T'
EquipmentGroup_Equipment
equipment_group_id equipment_id
1 1
1 2
EquipmentGroup
id name description
1 GRP1 Group 1
My wanted resultSet is:
Result
EquipmentGroup.name EquipmentGroup.description, Equipment.owner_indicator
GRP1 Group 1 (empty string)
That empty string would be returned because I don't want 2 rows, like
Result
EquipmentGroup.name EquipmentGroup.description, Equipment.owner_indicator
GRP1 Group 1 'T'
GRP1 Group 1 'V'
If anything more than that is needed please advise.
Thanks!
I thin k you must to use a main query on EquipmentGroup and a subquery about return data on Equipment.
If you have more than 1 equipment rows about one group you must return DISTINCT empty; if you have 1 row returns owner_indicator otherwise you can return 'None'
Try this:
SELECT DISTINCT eg.name, eg.description,
(SELECT
CASE
WHEN count(e.id) > 1 THEN DISTINCT 'EMPTY'
WHEN count(e.id) = 1 THEN e.owner_indicator
ELSE 'none'
END
FROM Equipment e
WHERE e.equipmentGroup.id = eg.id)
FROM EquipmentGroup eg

About solr query facet

In my solr document, the document data is like:
{
"createTime":"2013-09-10",
"reason":"reason1",
"postId":"postId_1",
"_version_":1445959401549594624 },
{
"createTime":"2013-09-11",
"reason":"reason2",
"postId":"postId_1",
"_version_":1445959401549594624 },
{
"createTime":"2013-09-12",
"reason":"reason3",
"postId":"postId_1",
"_version_":1445959401549594624 },
{
"createTime":"2013-09-13",
"reason":"reason4",
"postId":"postId_2",
"_version_":1445959401549594624 },<script>alert("1")</script>
Now I need use solr facetQuery to select some data like this:
1. postId1, 3 records, the last createTime is "2013-09-12"
2. postId2, 1 record, the last createTime is "2013-09-13", reason is reason4
How can I do this using solr facetQuery?
You can use Field Collapsing feature, which can help you group the results.
If you group on post_id, you would be able to get the the results as per the post id.
You would get the count for each post id (numFound), which will give you the 3 records part.
You can order the results within the group by date desc and return single result (group.limit=1) which will give you the last date.
You can pick up the reason from the records.

Categories

Resources