是否可以在 t-sql 中对组进行子查询?
我的目标是编写一个查询,该查询将返回带有 3 个标志字段的所有类别,如下所示:
ID |恩 |茹 | Fr
语言标志必须根据是否有与该类别关联的任何课程记录来打开或关闭。
我当前的声明是这样的:
SELECT c.ID,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 1) THEN 1 ELSE 0 END) AS En,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 2) THEN 1 ELSE 0 END) AS Ru,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 3) THEN 1 ELSE 0 END) AS Fr
FROM LessonCategories AS c
问题是这个查询非常慢,因为 Lessons 表有超过 60,000 条记录,而且我运行了 3 次。
我正在寻找一种方法来提高此查询的效率。 我曾想过在类别和课程之间的连接上使用分组,但我不知道具体如何以及是否可能。
更快速查询的伪代码是:
SELECT c.[ID],
COUNT(l.Language_Id = 1) > 0 AS En
COUNT(l.Language_Id = 2) > 0 AS Ru
COUNT(l.Language_Id = 3) > 0 AS Fr
FROM CategoryTreeView AS c
INNER JOIN Lessons AS l ON l.Category_Id = c.ID
GROUP BY c.[ID]
It it possible toexpress this using valid t-sql? 或者有什么更好的方法来处理这种查询?
PS 如果有帮助的话,我不在乎得到一个按位标志字段而不是 3 个语言字段。
谢谢。
My objective is to write a query that will return all the Categories with 3 flag fields, like this:
ID | En | Ru | Fr
The language flags must be ON or OFF according to if is any Lesson record associated with the category.
My current statement is this:
SELECT c.ID,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 1) THEN 1 ELSE 0 END) AS En,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 2) THEN 1 ELSE 0 END) AS Ru,
(CASE WHEN c.ID IN (SELECT c.ID FROM Lessons AS l WHERE l.Category_Id = c.ID AND l.Language_Id = 3) THEN 1 ELSE 0 END) AS Fr
FROM LessonCategories AS c
The problem is that this query is VERY slow, since the Lessons table has more than 60,000 records, and i'm running over it 3 times.
I'm looking for a way to make this query more efficient.
I had a thought to use grouping on join between Categories and lessons but i dont know exactly how and if it is even possible.
The pseudo-code for more fast query is:
SELECT c.[ID],
COUNT(l.Language_Id = 1) > 0 AS En
COUNT(l.Language_Id = 2) > 0 AS Ru
COUNT(l.Language_Id = 3) > 0 AS Fr
FROM CategoryTreeView AS c
INNER JOIN Lessons AS l ON l.Category_Id = c.ID
GROUP BY c.[ID]
It it possible to express this using valid t-sql?
Or is any better way to handle this kind of query?
P.S. If it helps, i don't care to get one bitwise flag field instead of the 3 language fields.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好吧,您只需将两个查询结合起来即可;)
Well you have just to combine your two queries ;)
您可以在第二个示例中使用计数:
但实际上,您想在第一个示例中使用
exists
:通过正确的索引,三个
exists
会快得多。You can go with counts in your second example:
But in fact, you want to use
exists
in your first example:With proper indexing, three
exists
s will be much faster.顺便说一句,试试这个
,
目前,您正在通过应用
CASE
语句在SELECT
子句中进行过滤。通过将过滤语句移至在SELECT
之前执行的WHERE
子句,您可以显着提高任何查询的性能。Try out this
BTW,
Currently you are doing filtering in
SELECT
clause by applyingCASE
statements. You can significantly improve performance of any query by moving filtering statements to theWHERE
clause which executes beforeSELECT
.一种完全不同的方法尝试枢轴。
测试在这里 https://data.stackexchange.com/stackoverflow/q/107960/
A completely different approach try pivot.
Test is here https://data.stackexchange.com/stackoverflow/q/107960/