簡體   English   中英

如何在 SELECT 之間使用“IN”編寫“JPQL”查詢?

[英]How to write "JPQL" query with "IN" between SELECTs?

我編寫了這個JPQL查詢並期望得到List<Question>的結果:

@Query("SELECT q FROM Question q WHERE q.id IN (SELECT qc.questions FROM QCard qc WHERE qc.id IN (SELECT ct.qCards FROM CTest ct WHERE ct.id=:id))")

這些是我的課:

class CTest {
  id List<QCard>
}

class QCard{
  id List<Question>
}

class Question{
  id
}

我希望所有問題都作為給定CTest.id的回報。 但是我收到了一個帶有消息的編譯器錯誤:

SQLSyntaxErrorException

我嘗試在“選擇”單詞之前使用“:”,但沒有幫助。

怎么了?

List<Question> findByIdIn(List<Long> idList); //In repository

或者

String qlString = "select i from Item i where i.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);
List<String> names = Arrays.asList("foo", "bar");
q.setParameter("names", names);
List<Item> actual = q.getResultList();

我在過去的工作中做了這些例子,檢查一下,tnx

在您現有的查詢中,在內部查詢中,您正在選擇實體並根據 Id 檢查 IN,這肯定是行不通的。 因為您無法使用 ID 完成輸入。

由於您尚未共享完整的實體結構,假設您在實體中正確聲明了兩種方式的關系,這里我放置了一個使用連接的參考查詢:

@Query("SELECT q FROM Question q JOIN q.qCard qc WHERE q.qCardId = qc.id AND qc.cTestId = :id")

其中qCardIdQuestion實體中QCard實體的外鍵引用, cTestIdQCard實體中CTest實體的外鍵引用。

您可以使用它作為參考來使用連接更新您的查詢。

在 SQL 客戶端(例如 Squirrel、DbVisualizer 等)中測試您的 SQL 查詢。

假設您的外鍵命名為:

  • QCard中的question_id
  • CTest中的card_id

你可以有一個 SQL 子選擇,如:

SELECT q.id
FROM Question q 
WHERE q.id IN (
  SELECT qc.question_id
  FROM QCard qc
  WHERE qc.id IN (
    SELECT ct.card_id
    FROM CTest ct
    WHERE ct.id = 1  -- example test id
  )
)

它是返回預期結果還是存在語法錯誤?

然后隨后用JOIN替換您的子選擇

  1. 問題和卡片
SELECT q.id, c.id
FROM Question q 
JOIN QCard c ON c.question_id = q.id
  1. 卡片和測試
SELECT c.id, t.id
FROM QCard c 
JOIN CTest t ON t.card_id = c.id
  1. 全部一起
SELECT q.id, c.id, t.id
FROM Question q 
JOIN QCard c ON c.question_id = q.id
JOIN CTest t ON t.card_id = c.id

注意:如果需要,添加WHERE子句,如WHERE t.id = 1

嘗試 FROM/JOIN 順序,因為它是有意義的。

然后將正在運行的 SQL 查詢轉換為 JPQL。 例如:

@Query("SELECT q"
+ " FROM CTest test" 
// a test has many cards (1:n)
+ " JOIN QCard card ON card.id = test.card_id"  // associated cards
// a card has many questions (1:n)
+ " JOIN Question q ON q.id = card.question_id"  // associated questions
+ " WHERE test.id = :id")
public List<Question> findQuestionsByTestId(String id);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM