Join multiple records on single record - mysql

I have this table (lineup):
ownerId (pk)
slot1 (fk heroId)
slot2 (fk heroId)
slot3 (fk heroId)
slot4 (fk heroId)
slot5 (fk heroId)
Now I need to retrieve the records from table (heroes) corresponding to the slots.
heroId (pk)
ownerId (fk)
templateId (fk)
...
And join this with the table (herotemplates).
templateId (pk)
...
So I came up with the following query:
String query = "SELECT * FROM lineup " +
"JOIN heroes AS slot1hero ON slot1hero.heroId = lineup.slot1 " +
"JOIN herotemplates AS slot1template ON slot1hero.templateId = slot1template.templateId " +
"JOIN heroes AS slot2hero ON slot2hero.heroId = lineup.slot2 " +
"JOIN herotemplates AS slot2template ON slot2hero.templateId = slot2template.templateId " +
"JOIN heroes AS slot3hero ON slot3hero.heroId = lineup.slot3 " +
"JOIN herotemplates AS slot3template ON slot3hero.templateId = slot3template.templateId " +
"JOIN heroes AS slot4hero ON slot4hero.heroId = lineup.slot4 " +
"JOIN herotemplates AS slot4template ON slot4hero.templateId = slot4template.templateId " +
"JOIN heroes AS slot5hero ON slot5hero.heroId = lineup.slot5 " +
"JOIN herotemplates AS slot5template ON slot5hero.templateId = slot5template.templateId " +
"WHERE lineup.ownerId = " + ownerId;
However, this returns an empty result. I highly suspect it's the query since I am not very experienced with complicated joins. Any idea what could be wrong with it?
I could fix this by normalizing lineup but I'm never going to use more ore less then 5 slots. I can also split into multiple queries but I'd rather query the database a single time and close the connection asap.

This is difficult to answer without knowing what data is in the table. You would need a match for each slot since you are using JOIN. I think you may need to be using LEFT JOIN.

Related

MYSQL query with LIKE condition doesn't give right result

I have database with different tables. I am trying to get emails from table Email if some conditions are met. One of condition is that name of advertisement from Ad table(given as parameter) has to contain text of suitable advertisement from SuitableAd table. I can't get this condition work(all other conditions works well).
#Query( "SELECT e.email FROM SuitableAd sad " +
"JOIN sad.author a JOIN a.email e " +
"WHERE :name LIKE '%sad.text%'" +
" AND (:price BETWEEN sad.priceFrom AND priceTo) AND sad.category = :category")
List<String> findBySuitableAd(#Param("name") String name, #Param("price")BigDecimal price, #Param("category")
String category);
Try this one
#Query( "SELECT e.email FROM SuitableAd sad " +
"JOIN sad.author a JOIN a.email e " +
"WHERE sad.text LIKE '%:name%'" +
" AND (:price BETWEEN sad.priceFrom AND priceTo) AND sad.category = :category")
List findBySuitableAd(#Param("name") String name, #Param("price")BigDecimal price, #Param("category")
String category);

Using a Variable in LEFT JOIN

I'm trying to create a single query that returns a result if the id is found in either Result1 or Result2, but also searches for that ID in another table to return the 'skill.'
The query is in a loop so the ID changes. How can I change the query below to utilize the variable ID to match something in a given table column?
query = "SELECT "
"a.Item1, a.Item2, a.Result1, a.Result2, b.skill "
"FROM formulas AS a "
"LEFT JOIN skills AS b "
"USING (%u AS Id) "
"WHERE Type != 0 AND Result1 = %u OR Result2 = %u;";
Area of concern is: USING (%u AS Id)
(Edit: Cleaned up code for readability)
Nevermind, I figured it out...I just used 'ON'...
query = "SELECT "
"a.Item1, a.Item2, a.Result1, a.Result2, b.skill "
"FROM formulas AS a "
"LEFT JOIN skills AS b "
"ON (Id = %u) "
"WHERE Type != 0 AND Result1 = %u OR Result2 = %u;";

NonUniqueDiscoveredSqlAliasException for MySQL query that works in phpMyAdmin

I have a table with four foreign keys and an image:
+--------------+--------------+---------------------+---------------------+-------+
| dataset_1_fk | dataset_2_fk | attribute_type_1_fk | attribute_type_2_fk | image |
+--------------+--------------+---------------------+---------------------+-------+
Using the name of two datasets, I would like to select the image and names of the two attributes. Here is my Hibernate code:
HibernateUtil
.getCurrentSession()
.createSQLQuery(
"SELECT ddm.image, at1.name, at2.name " +
"FROM dataset_dataset_matrices AS ddm " +
" JOIN dataset AS d1 ON d1.id = ddm.dataset_1_fk " +
" JOIN dataset AS d2 ON d2.id = ddm.dataset_2_fk " +
" JOIN attribute_type AS at1 ON at1.id = ddm.attribute_type_1_fk " +
" JOIN attribute_type AS at2 ON at2.id = ddm.attribute_type_2_fk " +
"WHERE d1.name = :dataset_1 AND d2.name = :dataset_2"
)
.setString("dataset_1", dataset_1)
.setString("dataset_2", dataset_2)
.list();
I receive this error when it executes:
org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [name] during auto-discovery of a native-sql query
at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:594)
But when I issue the same query from phpMyAdmin, it works fine. Also, if I remove either at1.name or at2.name from the SELECT statement, the query works in Hibernate. How can I fix this?
Try giving different alias name to your select columns like
"SELECT ddm.image as col1, at1.name as col2, at2.name as col3"
It seems hibernate doesn't generate the different alias automatically. If the query results has same values this issue may happens.
Reference : https://github.com/querydsl/querydsl/issues/80

with-clause not allowed on fetched associations

I have a name query like the one below - but keep getting an error from Hibernate that it will not allow my 'with'-clause since I'm doing join fetch.
I need to do join fetch - because it there is a related item then I wan't it to be present on the object.
#NamedQuery(name = "Item.findItem",
query = "SELECT DISTINCT(c) FROM Item c " +
"JOIN FETCH c.storeRelations as childStoreRelation " +
"LEFT JOIN FETCH c.relatedItems as relatedRelations WITH relatedRelations.store.id = childStoreRelation.store.id " +
"WHERE c.id = :itemId " +
"AND childStoreRelation.store.id = :storeId " +
"AND childStoreRelation.deleted <> 'Y' " +
"ORDER BY c.partnumber "),
Suggestion would be to move the 'with' part to my where clause - but this will cause invalid results.
Consider item A which might have to items related to it - but for some stores the relations are not valid.
If put in where clause then the store without relations will not shown the main item, since SQL will be build by Hibernate so it requires that if any relations exist, then they must be valid for the store - otherwise nothing is fetched :-(
So the classic fix found many places (store.id is null OR store.id = :storeId) will not work.
Does someone have another work around?
I'm running Hibernate 4.3.11
Thanks in advance
You cannot use LEFT JOIN FETCH with clause.
Please remove WITH clause and move them to WHERE clause.
It should like this:
#NamedQuery(name = "Item.findItem",
query = "SELECT DISTINCT(c) FROM Item c " +
"JOIN FETCH c.storeRelations as childStoreRelation " +
"LEFT JOIN FETCH c.relatedItems as relatedRelations " +
"WHERE c.id = :itemId " +
"AND relatedRelations.store.id = childStoreRelation.store.id" +
"AND childStoreRelation.store.id = :storeId " +
"AND childStoreRelation.deleted <> 'Y' " +
"ORDER BY c.partnumber "),
You need the ON keyword rather than the WITH keyword.

Complex JPQL ORDER statement

I'm trying to write a fairly complex JPQL statement that sorts results based on a value in another table. I know what the MySQL would look like, but I need help turning it into JPQL. Here's the equivalent SQL:
SELECT o.* FROM Observation o
LEFT JOIN Obs_Event p
ON p.Event_ID = o.Event_ID
LEFT JOIN Event_Set ppp
ON ppp.Event_ID = o.Event_ID AND ppp.Event_Set_ID = o.Event_Set_ID
WHERE o.Individual_ID = <some id>
AND o.Observation_Date = <a date value>
ORDER BY ppp.Seq_Num ASC
Any help on how to do this would be much appreciated. Specifically I seem to having trouble with this part:
ON ppp.Event_ID = o.Event_ID AND ppp.Event_Set_ID = o.Event_Set_ID
So, far I've tried this:
Query q= em.createQuery("select o " +
" from Observation as o " +
" join o.eventID p" +
" join p.eventSetCollection ppp " +
" where o.individualID = :indiv " +
" AND o.observationDate = :d " +
" AND o.eventID = ppp.event " +
"";
If I try to add something like
WHERE ...
AND o.eventSetID = ppp.eventSet
... it simply doesn't work. If I look at the generated SQL, it looks like ppp.eventSet is simply ignored.
Suggestions?
So, first thanks to the poster that commented, asking for my entity relationships. That forced me to take a closer look at things and realize what was wrong.
As it turns out, back when I was even worse at JPA than I am now, I set the o.eventID property to an actual Integer, as in the primary key of the record/object, instead of an actual object. Hence, in the JPQL above, I'm actually trying to map an object to an integer in the following statement:
AND o.eventID = ppp.event
turns out the correct statement is:
Query q= em.createQuery("select o " +
" from Observation as o " +
" join o.eventID p" +
" join p.eventSetCollection ppp " +
" where o.individualID = :indiv " +
" AND o.observationDate = :d " +
" AND o.eventID= ppp.event.eventID" +
" order by ppp.seqNum ASC" +
"");
This works in a pinch, although I should eventually change that relationship in the Observation class to actually go to an object.