2017-12-18 32 views
0

jooq APIに次の文を変換しながら、私は問題を抱えている:JOOQ - 選択クエリ内のSELECT COUNT

SELECT t1.col1, t1.col2, t1.col3, (SELECT count(*) FROM table2 where table2.col2 = t1.col1) 
FROM table1 t1 

私はDSL.count()DSL.selectCount()でそれを試みただけに、where句を追加する方法を探している間、私は失敗しましたカウントサブクエリ。

データベースはPostgreSQL 9.6です。

答えて

1

タイプを保持しているため、ルーカスが使用する提案はDSL.fieldです。

もっと型保証されたバージョン:

TableField<Table1Record, Long> col1 = TABLE1.COL1; 
Field<Integer> count = DSL.field(DSL.selectCount().from(TABLE2).where(TABLE2.COL2.eq(col1))); 
using(configuration).select(col1, count).from(TABLE1).fetch(); 

私の最初の(少ないタイプセーフな)解決策:

TableField<Table1Record, Long> col1 = TABLE1.COL1; 
Field count = DSL.selectCount().from(TABLE2).where(TABLE2.COL2.eq(col1)).asField("count"); 
using(configuration).select(col1, count).from(TABLE1).fetch(); 

はたぶん、よりエレガントな解決策があるが、それは動作します。生成されたクエリは、私の元のクエリのように見えます。

+0

['FieldLike.asField()'](https://www.jooq.org/javadoc/latest/org/jooq/FieldLike.html#asField--)はそれを行う方法の1つです。もう一つは、['DSL.field(Select)'](https://www.jooq.org/javadoc/latest/org/jooq/impl/DSL.html#field-org.jooq)を使って相関サブクエリをラップすることです.Select-)、これは ''タイプを保持し、rawtypeの使用を防ぎます。 –

0

ここDSL.field(...)を使用して別の例である:

 Field<Integer> COUNT = DSL.field("COUNT(*) OVER()", Integer.class); 

    List<Map<String, Object>> records = DSL.select(ACCESSORY.ID, 
       ACCESSORY.NAME, 
       ACCESSORY.TYPE, 
       ACCESSORY.PRICE, 
       BRAND.NAME, 
       COUNT.as("total")) 
      .from(ACCESSORY) 
      .innerJoin(BRAND).onKey() 
      .fetchMaps(); 

ResultSetがタイプjava.lang.Integerとして扱われtotalという列を含むであろう。これはPostgreSQL 9.6で動作します。

COUNT(*) OVER()の詳細な説明は、hereです。