我的SQL查询看起来像这样:
SELECT
o.name,
o.type_id,
(SELECT COUNT(*) FROM a WHERE type_id = o.type_id AND id IN ('1, 2, 3 ... 1000')) AS count_a,
(SELECT COUNT(*) FROM b WHERE type_id = o.type_id AND id IN ('1, 2, 3 ... 1000')) AS count_b,
(SELECT COUNT(*) FROM c WHERE type_id = o.type_id AND id IN ('1, 2, 3 ... 1000')) AS count_c
FROM o
在子查询(count_a,count_b和count_c)中,IN子句中指定的条件对于每个条件都是相同的,但它是一个非常长的数字列表(实际上不是顺序的),并且我担心:
a)我把查询放慢了太长时间了 b)它会变得太长并最终导致错误
有没有办法别名/引用该标准列表(可能作为变量?),以便可以在查询中出现的三个位置中的每个位置重复使用它?或者我什么都不担心?
更新
鉴于使用CTE的建议,我已将上面的查询改为现在这样工作:
WITH id_list AS (SELECT id FROM source WHERE id IN ('1, 2, 3 ... 1000'))
SELECT
o.name,
o.type_id,
(SELECT COUNT(*) FROM a WHERE type_id = o.type_id AND id IN (SELECT id FROM id_list)) AS count_a,
(SELECT COUNT(*) FROM b WHERE type_id = o.type_id AND id IN (SELECT id FROM id_list)) AS count_b,
(SELECT COUNT(*) FROM c WHERE type_id = o.type_id AND id IN (SELECT id FROM id_list)) AS count_c
FROM o
这会将查询的总长度减少到原来的三分之一,虽然数据库似乎需要花费几毫秒才能执行查询,但至少我不会遇到基于长度的错误查询太长了。
问题:有没有一种快速方法可以将逗号分隔的数字列表(1,2,3 ... 1000)分解为可用作CTE的结果集?
答案 0 :(得分:3)
您可以使用common-table-expression(CTE):
WITH Numbers AS
(
SELECT N
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 1000)
AS T(N)
)
SELECT
o.name,
o.type_id,
(SELECT COUNT(*) FROM a WHERE type_id = o.type_id AND id IN (SELECT N FROM Numbers)) AS count_a,
(SELECT COUNT(*) FROM b WHERE type_id = o.type_id AND id IN (SELECT N FROM Numbers)) AS count_b,
(SELECT COUNT(*) FROM c WHERE type_id = o.type_id AND id IN (SELECT N FROM Numbers)) AS count_c
FROM o
答案 1 :(得分:0)
如果你的id是其他表中的外键,那么你可以从列表中创建一个表变量,然后重复加入。
DECLARE @id_list TABLE (
id INT
)
INSERT INTO @id_list
SELECT id
FROM pk_location
WHERE id IN ('1, 2, 3 ... 1000')
SELECT
o.name,
o.type_id,
(SELECT COUNT(*) FROM a INNER JOIN @id_list i ON a.id = i.id WHERE type_id = o.type_id) AS count_a,
(SELECT COUNT(*) FROM b INNER JOIN @id_list i ON b.id = i.id WHERE type_id = o.type_id) AS count_b,
(SELECT COUNT(*) FROM c INNER JOIN @id_list i ON c.id = i.id WHERE type_id = o.type_id) AS count_c
FROM o