繁体   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