1

When I try to execute two SELECT statements at once as follows below, the logging console returns a runtime error:

java.sql.SQLSyntaxErrorException: 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 'SELECT * FROM ...

The Java source code that generates the statements:

@Repository
public class VehicleObjectDbAccess {
    @PersistenceContext
    EntityManager entityManager;

    public List<Object[]>  getObjectById(long objectId, long year)     
    {
        int limit = 10;
        String tableName = ("i0i"+year)+objectId;
        String queryText =
            "START TRANSACTION;"
            + "SELECT t.created INTO @startTime FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1;"
            + "SELECT * FROM ObjectTable WHERE created <= (CASE WHEN @startTime IS NULL THEN NOW() ELSE @startTime END) ORDER BY created DESC LIMIT 10;"
            + "COMMIT;";

        Query query = this.entityManager.createNativeQuery(queryText);
        return query.getResultList();
    }
}

Eventually the java source code above translates to

START TRANSACTION; 
SELECT t.created INTO @startTime FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1;
SELECT * FROM ObjectTable WHERE created <= (CASE WHEN @startTime IS NULL THEN NOW() ELSE @startTime END) ORDER BY created DESC LIMIT 10; 
COMMIT;

I verified that SQL code running it on a MySQL client and it works properly.

How can I execute these two SELECT statements in a single query?

2 Answers 2

1

It seems you can divide your compound sql query to two separate SELECT queries:

 Query query1 = this.entityManager.createNativeQuery(queryText1);
 Query query2 = this.entityManager.createNativeQuery(queryText2);

After that you can get result lists from them and add result lists to one compound List:

 List<Object[]> result = new ArrayList<>();
 result.addAll(query1.getResultList());
 result.addAll(query2.getResultList());
Sign up to request clarification or add additional context in comments.

3 Comments

I want to avoid dividing them into chunks, because doing so will lead to a greater computational time. I'm aiming to the fastest execution time.
"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs" - Donald Knuth in "Structured Programming With Go To Statements" - 1974
@mikeb Stackoverflowers waste enormous amounts of time thinking about, or worrying about, strangers in unknown codebases doing premature optimization.
1

Just use one select statement:

SELECT *, (SELECT t.created FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1) as x FROM ObjectTable WHERE created <= 
  (CASE WHEN x IS NULL THEN NOW() 
   ELSE x
  END) 
  ORDER BY created DESC LIMIT 10;

If you don't want to do this for some reason, create a stored procedure that returns a result set and call it...

4 Comments

I want to avoid nested SELECT statements. The queries in my question are shortened for simplicity. The actual queries are longer. Combining them into a single nested SELECT statement would make the query unreadble.
See my edits - create a stored procedure in your DB and call it - that would be my alternative.
Unfortunately, I cannot use stored procedure because the name of database table is going to be dynamic and MySQL doesn't allow me to specify the table name on the go in a procedure.
So use the nested selects. You are going to spend an absurd amount your time trying to make 3-5 lines of your solution "readable" (this is very subjective anyway), fast and "correct". At some point it has to work so you can go on to other things.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.