I'm trying to get result from 3 inner join in java code with sql.
I tried this
BeanHandler rsh=new BeanHandler(evaluation.class);
evaluation eval=(evaluation) runner.query(query,new Object[]{userid}, rsh);
This code return the result from query, but with "join" statement it's not working, I want to get result from 3 tables.
any ideas?
Edit: (the query)
String query=" select users.username, sum(evaluation.mark)\n" +
"from users inner JOIN user_has_eval \n" +
"on users.id= user_has_eval.user_id inner JOIN\n" +
"evaluation ON evaluation.id=user_has_eval.eval_id\n" +
"where evaluation.types=\"Secretaria\" and users.id = ? \n" +
"\n" ;
Related
I wrote this SQL Query and using it as a native query in hibernate.
#Query(
value = "SELECT DISTINCT tp.* FROM TWITTER_POST AS tp " +
"JOIN TWITTER_LIST AS tl " +
"ON tl.owner_id = ?1 " +
"JOIN REL_TWITTER_LIST__ACCOUNTS_TRACKED_BY_LIST AS atbl " +
"ON tl.id = atbl.twitter_list_id " +
"JOIN TWITTER_ACCOUNT AS ta " +
"ON ta.id = atbl.accounts_tracked_by_list_id " +
"LEFT OUTER JOIN REL_TWITTER_POST__TWITTER_USERS_HIDING_POST uhp " +
"ON tp.id = uhp.twitter_post_id " +
"AND uhp.TWITTER_USERS_HIDING_POST_ID = ?1 " +
"WHERE uhp.twitter_post_id is NULL AND ta.id = tp.author_id",
countQuery = "SELECT DISTINCT count(tp.*) FROM TWITTER_POST AS tp " +
"JOIN TWITTER_LIST AS tl " +
"ON tl.owner_id = ?1 " +
"JOIN REL_TWITTER_LIST__ACCOUNTS_TRACKED_BY_LIST AS atbl " +
"ON tl.id = atbl.twitter_list_id " +
"JOIN TWITTER_ACCOUNT AS ta " +
"ON ta.id = atbl.accounts_tracked_by_list_id " +
"LEFT OUTER JOIN REL_TWITTER_POST__TWITTER_USERS_HIDING_POST uhp " +
"ON tp.id = uhp.twitter_post_id " +
"AND uhp.TWITTER_USERS_HIDING_POST_ID = ?1 " +
"WHERE uhp.twitter_post_id is NULL AND ta.id = tp.author_id",
nativeQuery = true
)
Page<TwitterPost> findAllNonHiddenForListsFromTwitterAccountId(Long twitterAccountId, Pageable pageable);
I noticed that the query executes very slowly when I'm running it through hibernate as opposed to a SQL tool. I assumed it was because I am using a native query as opposed to JQPL, which (from what I read) immediately does caching and pagination without requiring a definition for "count". Trying to convert it to JQPL failed, because I cannot find a good tutorial for more complicated queries on JQPL across join tables.
#Query(
value = "SELECT DISTINCT twitterPost " +
"FROM TwitterPost twitterPost " +
"JOIN TwitterList twitterList " +
"ON twitterList.owner.id = ?1 " +
"JOIN TwitterAccount tweetAuthorFromList " +
"ON tweetAuthorFromList IN twitterList.accountsTrackedByLists " +
"WHERE twitterPost.author = tweetAuthorFromList " +
"AND twitterList.owner NOT IN twitterPost.twitterUsersHidingPosts"
)
Page<TwitterPost> findAllNonHiddenPostsFromListsForTwitterAccountId(Long twitterAccountId, Pageable pageable);
Apparently my Syntax is off
org.hibernate.exception.SQLGrammarException: could not prepare
statement
but the compiler only shows me problems with the generated SQL, not the JQPL so I'm left in the dark.
Also checked for typical bad performance culprits i.e. eager fetching of entities which I set to lazy everywhere.
Any help regarding whether my performance problem assumptions are correct, or converting the query, are highly appreciated - thanks in advance!
There are many things that are wrong here:
Using SELECT DISTINCT with JOIN indicates that you should have used a Semi Join instead.
The ON tl.owner_id = ?1 is done for filtering, not for the projection, hence you are better off doing an EXISTS query.
Assuming why the query runs slow instead of profiling it. The reason why it runs faster in the DB tool is that DB tools usually truncate the result set while Spring Data consumes the entire result set. Or, if you run EXPLAIN, the output might come from the Optimizer without even running the query.
So, here's what you can do:
Use Semi Joins instead of Joins for filtering.
Use Blaze Persistence to write better entity queries dynamically.
Configure Statement Caching at the JDBC Driver level.
Use the slow query log to log the execution plan when the query is slower than N seconds.
I am working on Spark SQL and I am trying to get the records using following queries:
/*Select all open tasks which are not unscheduled*/
Dataset<Row> scheduledOpenTasks = sqlContext.sql(
"SELECT * "
+ "FROM OpenTaskTable "
+ "WHERE due_date < cast('" + unscheduledDate + "' as timestamp)");
scheduledOpenTasks.createOrReplaceTempView("ScheduledOpenTaskTable");
/*Select scheduled tasks with max due_date for each csg_order_id*/
Dataset<Row> scheduledTasks = sqlContext.sql(
"SELECT TS1.* from ScheduledOpenTaskTable AS TS1 "
+ "INNER JOIN "
+ " (SELECT csg_order_id, MAX(due_date) AS MaxDD"
+ " FROM ScheduledOpenTaskTable"
+ " GROUP BY csg_order_id) AS TS2 "
+ "ON TS1.csg_order_id = TS2.csg_order_id AND TS1.due_date = TS2.MaxDD");
The unscheduled _date has value 4444-12-30.
In the OpenTaskTable, each csg_order_id can have multiple due_dates including unscheduled_date. I need the csg_order_ids with corresponding highest due_dates except unscheduled_date.
Now, with first query, I am removing all the records which have due_date as unscheduled_date. In second query, I am retrieving all the records with max due_date for each csg_order_id.
Now comes the problem: is there any way to combine these queries as one?
Well, after struggling for a while, finally found a way to combine the above two queries like this:
sqlContext.sql("SELECT OT1.* from OpenTaskTable AS OT1 INNER JOIN "
+ "(SELECT OT2.csg_order_id, MAX(OT2.due_date) AS MaxDD FROM "
+ "(SELECT csg_order_id, due_date from OpenTaskTable WHERE due_date < cast('"+unscheduledDate+"' as timestamp)) AS OT2 "
+ "GROUP BY OT2.csg_order_id) AS OT3 "
+ "ON OT1.csg_order_id = OT3.csg_order_id AND OT1.due_date = OT3.MaxDD");
Explanation:
Previously, in the first query, I was retrieving data from OpenTaskTable and then feeding it to the second query. Logically, in the second query also, I am just applying more filters over the retrieved data. At the end, we are trying to get all the attributes from OpenTaskTable only.
So, for this solution I simply used the first query, as the innermost query, and then selected MAX over the records grouped by csg_order_id. And, for the outermost query, just performed an inner join to get all matching csg_order_id records from OpenTaskTable.
Trying to join 3 tables within a query returns an empty result. Strange enough, having one table removed (two tables join) returns some set. Here is what I do:
String sql = "SELECT\n" +
" tc.constraint_name, tc.table_name, kcu.column_name, \n" +
" ccu.table_name AS foreign_table_name,\n" +
" ccu.column_name AS foreign_column_name, constraint_type \n" +
"FROM \n" +
" information_schema.table_constraints AS tc \n" +
" JOIN information_schema.key_column_usage AS kcu\n" +
" ON tc.constraint_name = kcu.constraint_name\n" +
" JOIN information_schema.constraint_column_usage AS ccu\n" +
" ON ccu.constraint_name = tc.constraint_name\n" +
"WHERE constraint_type = 'FOREIGN KEY'";
List<Map<String, Object>> foreignTable1 = jdbcTemplate(getShardId(sku)).queryForList(sql);
Would always return an empty set.
Try using outer joins and check whether there are rows which don't have corresponding IDs so that the join removes the non-matching rows. Especially that you write, that two tables result in a non-empty result set seems to indicate, that the join with the third table does not result in matching rows of the result set of the first two.
I don`t get it. I created a query where made some joins of two tables in SQLite. In my SQLite Browser there is all ok and the columns are displayed correctly. But when I call executeQuery, I always get the error:
[SQLITE_ERROR] SQL error or missing database (no such column: td.value)
Here is my statement:
private static final String QUERY_ENDUSES = "SELECT td.Value Value, reportn.Value ReportName, fs.Value ReportForString, tn.Value TableName, rn.Value RowName, cn.Value ColumnName, u.Value Units, RowId "
+ "FROM TabularData td"
+ "INNER JOIN Strings reportn ON reportn.StringIndex=td.ReportNameIndex "
+ "INNER JOIN Strings fs ON fs.StringIndex=td.ReportForStringIndex "
+ "INNER JOIN Strings tn ON tn.StringIndex=td.TableNameIndex "
+ "INNER JOIN Strings rn ON rn.StringIndex=td.RowNameIndex "
+ "INNER JOIN Strings cn ON cn.StringIndex=td.ColumnNameIndex "
+ "INNER JOIN Strings u ON u.StringIndex=td.UnitsIndex WHERE report n.StringTypeIndex=1 AND fs.StringTypeIndex=2 AND tn.StringTypeIndex=3 AND rn.StringTypeIndex=4 AND cn.StringTypeIndex=5 AND u.StringTypeIndex=6 "
+ "AND td.ReportNameIndex = 1 AND tn.StringIndex = 59;";
If I substitute the statement through Select td.value from TabularData td , then all is OK!
Can anybody help me?
You're missing a space between td in the FROM clause, and the first INNER.
Problem Synopsis:
When attempting to execute a SQL query in Java with a SQLite Database, the SQL statement fails to return from the execute() or executeQuery() method. In other words, the system "hangs" when executing this SQL statement.
Question:
What am I doing wrong to explain why the ResultSet never "returns?"
TroubleShooting
I tried to narrow the problem and the problem seems to be with the Java execute() or executeQuery(). A ResultSet never seems to return. For example, I tried executing exactly the same query directly in SQLite (that is, using a SQLite DB manager). The query (outside Java) executes in about 5ms and returns the valid result set.
NOTE: No exception is thrown. The system merely seems to "hang" and becomes unresponsive until a manual kill. (waiting more than 10 minutes.)
Code:
I heavily edited this code to make the problem simpler to see. (In production, this uses Prepared Statements. But, the error occurs in both methods--straight Statement and prepared Statement versions.)
Basically, the SELECT returns a single DB item so the user can review that item.
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT d1.id, d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;
Configuration:
Java 6,
JDBC Driver = Xerial sqlite-jdbc-3.7.2,
SQLite 3,
Windows
Update
Minor revision: as I continue to work with this, adding a MIN(d1.id) to the beginning of the SQL statement at least returns a ResultSet (rather than "hanging"). But, this is not really what I wanted as the MIN obviates the LIMIT function.
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT MIN(d1.id), d1.id,
d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;
What a messy SQL statement (sorry)! I don't know SQLite, but why not simplify to:
SELECT DISTINCT md.id, md.sourcefullfilepath, md.sourcefilepath, md.sourcefilename,
dc.classificationid, dc.classid, dc.userid
FROM MatterDataset md
LEFT JOIN DocumentClassification dc
ON dc.documentid = md.id
AND (dc.classid = 1 OR dc.classid = 2 )
AND dc.userid < 0
LEFT JOIN PrivilegeLog pl
ON md.id = pl.documentparentid
AND md.matterid = pl.matterid
WHERE pl.privilegelogitemid IS NULL
AND md.matterid = \'100\'
ORDER BY md.id LIMIT 1 ;
I was uncertain whether you wanted to LEFT JOIN or INNER JOIN to DocumentClassification (using LEFT JOIN and then put requirements on classid and userid in the WHERE statement is - in my opinion - contradictory). If DocumentClassification has to exist, then change to INNER JOIN and put the references to classid and userid into the WHERE clause, if DocumentClassification may or may not exist in your result set, then keep the query as I suggested above.
I went back and started over. The SQL syntax, while it worked outside Java, simply seemed too complex for the JDBC driver. This cleaned-up revision seems to work:
SELECT DISTINCT
MatterDataset.id, MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath,
MatterDataset.sourcefilename
FROM MatterDataset , DocumentClassification
ON DocumentClassification.documentid = MatterDataset.id
AND MatterDataset.matterid = DocumentClassification.matterid
LEFT JOIN PrivilegeLog ON MatterDataset.id = PrivilegeLog.documentparentid
AND MatterDataset.matterid = PrivilegeLog.matterid
WHERE PrivilegeLog.privilegelogitemid IS NULL
AND MatterDataset.matterid = '100'
AND (DocumentClassification.classid = 1 OR DocumentClassification.classid = 2)
AND DocumentClassification.userid = -99
ORDER BY MatterDataset.id LIMIT 1;
A nice lesson in: just because you can in SQL doesn't mean you should.
What this statement does is essentially locates items in the MatterDataset Table that are NOT in the PrivilegeLog table. The LEFT JOIN and IS NULL syntax locate the items that are "missing." That is, i want to find items that are in MatterDataset but not yet in PrivilegeLog and return those items.