Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subquery in join

I need to select companies from the database with their active addresses (address.address_status_id = 1). If the address is inactive the address columns should contain nulls.

The following query does exactly what I want:

select c.id, c.name, a.id, a.street
from company c
left join 
(select * from address where address_status_id = 1) a 
on c.id = a.company_id

I tried this in Java/QueryDSL:

JPAQuery query = new JPAQuery(entityManager);
query = query.from(qCompany);
query = query.leftJoin(company.addresses, new JPASubQuery().from(qAddress)    
.where(qAddress.addressStatusId.eq(AddressStatuss.ACTIVE.asBigDecimal())).list(qAddress));

However JPA (and consequently the JPAQuery in QueryDSL) doesn't support a subquery in a JOIN clause

Is there a way to rephrase the SQL statement so that it can be expressed in JPA/QueryDSL?

edit: We're using Oracle DB and Hibernate JPA provider if it makes a difference.

like image 212
kosmičák Avatar asked Jul 10 '13 07:07

kosmičák


People also ask

Can we use subquery in JOIN?

Subqueries can be used as an alternative to joins.

How do you write a subquery in JOIN?

A subquery can be used with JOIN operation. In the example below, the subquery actually returns a temporary table which is handled by database server in memory. The temporary table from the subquery is given an alias so that we can refer to it in the outer select statement.

Which is faster subquery or JOIN?

The advantage of a join includes that it executes faster. The retrieval time of the query using joins almost always will be faster than that of a subquery. By using joins, you can maximize the calculation burden on the database i.e., instead of multiple queries using one join query.

Should you use a JOIN or a subquery?

If you need to combine related information from different rows within a table, then you can join the table with itself. Use subqueries when the result that you want requires more than one query and each subquery provides a subset of the table involved in the query.


2 Answers

Maybe like this

select c.id, c.name, a.id, a.street
from Company c
left join c.addresses a on a.addressStatusId = 1

and in Querydsl

query.from(c)
     .leftJoin(c.addresses, a)
     .on(a.addressStatusId.eq(1))
     .list(c.id, c.name, a.id, a.street)
like image 96
Timo Westkämper Avatar answered Oct 05 '22 23:10

Timo Westkämper


I would use the Oracle DB JDBC. You can get that here.

Depending on wether you are trying to build an Applet or Application, you will have to choose between the tiny and the OCI version of the JDBC. More information on that here.

Im going to assume that you are building an application, hence I will use OCI in this example.

Class.forName("oracle.jdbc.OracleDriver");
Connection con = null;
Statement stmt = null;
ResultSet rset = null;
try{
    con = DriverManager.getConnection("jdbc:oracle:oci:@//192.168.1.100", "user", "password");

    stmt = con.prepareStatement();

    rset = stmt.executeQuery("SELECT name, address, phonenumber FROM tbl_comanies");

    while(rset.next()){
        String name = rset.getString(1);
        String address = rset.getString(2);
        int phonenumber = rset.getInt(3);
        //The number passed to the get...()-Method is the place in the SQL query. (Here, name=1, address=2, phonenumber=3)
    }
} catch (SQLException ex) {
    System.out.println(ex.getMessage());
} finally {
    try {
        if(rset != null)
            rset.close();
        if(stmt != null)
            stmt.close();
        if(con != null)
            con.close();
    }
}

Hope this helps you out.

Regards, Andy

like image 23
AndMim Avatar answered Oct 06 '22 00:10

AndMim