2016-08-30 35 views
3

我想編寫JPA 2.1標準API這個SQL查詢:如何在內部查詢中引用外部查詢的成員?

select * from t_question q 
where 
(select count(*) from t_question_tag tag 
    where 
     q.question_id = tag.question_id 
     AND tag.tag_id in (18, 1) 
) = 2; 

我無法弄清楚如何引用外部問題成員內部查詢。

我目前在這一點上:

 CriteriaQuery<Question> cq = criteriaBuilder.createQuery(Question.class); 
Root<Question> questions = cq.from(Question.class); 
cq.distinct(true); 

    Subquery<Long> selectTags = cq.subquery(Long.class); 
    Root<QuestionTag> qt = selectTags.from(QuestionTag.class); 
    Join<QuestionTag, Question> qtJoin = qt.join("question"); 
    selectTags 
    .select(criteriaBuilder.count(qtJoin)) 
    .where(
     qt.get("tag").in(filter.getTags()) 
     ); 
    cq.where(criteriaBuilder.and(insArray), 
     criteriaBuilder.equal(criteriaBuilder.literal(filter.getTags().size()), selectTags)); 

但它創建了第二個加入。 SQL結果是:

SELECT DISTINCT ... 
FROM T_QUESTION question0_ 
WHERE 1     = 
    (SELECT COUNT(question3_.question_id) 
    FROM T_QUESTION_TAG questionta2_ 
    INNER JOIN T_QUESTION question3_ 
    ON questionta2_.question_id=question3_.question_id 
    WHERE questionta2_.tag_id IN (18)); 
+0

在你的第二個代碼片段中,'cq'代表什麼? (請相應更新代碼片段) – Riduidel

+0

我並不確切知道JPA如何在這一點上工作,但似乎您的WHERE ... = 2成爲WHERE 1 = – Riduidel

回答

1

我期望子查詢更喜歡這個

Subquery<Long> selectTags = cq.subquery(Long.class); 
Root<QuestionTag> qt = selectTags.from(QuestionTag.class); 
selectTags.select(criteriaBuilder.count(qt)); 
selectTags.where(
     criteriaBuilder.equal(questions.get("id"), qt.get("id")), 
     qt.get("tag").in(filter.getTags()) 
     ); 

從外部查詢使用候補(「問題」)來引用外部查詢,和唐你不明白你之前爲什麼要加入。我假定「問題」和「標記」中的字段都被稱爲「ID」。