我想知道如何重做/改进此查询(运行时间太长)。
一些背景信息: 订单ID => 'ID' 购买ID => '的pid' “表”是购买行的表,id是订单的id,订单可以有多行。例如,可以有三行ID为1,具有各种购买ID,因此:
id | PID
1 | 3
1 | 3
1 | 46
查询的目的是查找从多个产品系列中购买的订单,例如1,21,31,41和2,22,32,42。
下面的查询是我提出的,但它从所有子查询运行得非常慢,是否可以优化此查询或使用不同的更快查询获得相同的结果?
SELECT a.id
FROM Table AS a
GROUP BY a.id
HAVING (
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('1', '21', '31', '41') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('2', '22', '32', '42') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('3', '23', '33', '43') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('4', '24', '34', '44') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('5', '25', '35', '45') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('6', '26', '36', '46') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('7', '27', '37', '47') AND id = a.id ) THEN 1 ELSE 0 END AS INT) +
CAST( CASE WHEN EXISTS (SELECT NULL FROM Table WHERE pid IN ('8', '28', '38', '48') AND id = a.id ) THEN 1 ELSE 0 END AS INT)
) > 1
编辑:
最终工作查询(比以前快97%):
SELECT y.Id
FROM (SELECT x.Id,
x.productLine
FROM ( SELECT a.id,
CASE
WHEN a.pid IN ('1', '21', '31', '41') THEN 1
WHEN a.pid IN ('2', '22', '32', '42') THEN 2
WHEN a.pid IN ('3', '23', '33', '43') THEN 3
WHEN a.pid IN ('4', '24', '34', '44') THEN 4
WHEN a.pid IN ('5', '25', '35', '45') THEN 5
WHEN a.pid IN ('6', '26', '36', '46') THEN 6
WHEN a.pid IN ('7', '27', '37', '47') THEN 7
WHEN a.pid IN ('8', '28', '38', '48') THEN 8
ELSE 9
END AS productLine
FROM Table AS a
WHERE a.pid IN ('1', '21', '31', '41','2', '22', '32', '42','3', '23', '33', '43','4', '24', '34', '44','5', '25', '35', '45','6', '26', '36', '46','7', '27', '37', '47','8', '28', '38', '48')
) AS x
GROUP BY x.Id, x.productLine
) AS y
GROUP BY y.Id
HAVING COUNT(*) > 1
答案 0 :(得分:1)
据我所知,您的问题此查询应符合您的要求:
SELECT x.Id
FROM ( SELECT a.Id ,
CAST(a.pid AS INT) % 10 AS pid
FROM [Table] AS a
GROUP BY a.Id ,
CAST(a.pid AS INT) % 10
) x
GROUP BY x.Id
HAVING COUNT(*) > 1
考虑到新的假设后,查询应如下所示:
SELECT y.Id
(SELECT x.Id,
x.pid
FROM ( SELECT a.id,
CASE WHEN a.pid IN ('1', '21', '31', '41') THEN 1
WHEN a.pid IN ('2', '22', '32', '42') THEN 2
WHEN a.pid IN ('3', '23', '33', '43') THEN 3
WHEN a.pid IN ('4', '24', '34', '44') THEN 4
WHEN a.pid IN ('5', '25', '35', '45') THEN 5
WHEN a.pid IN ('6', '26', '36', '46') THEN 6
WHEN a.pid IN ('7', '27', '37', '47') THEN 7
WHEN a.pid IN ('8', '28', '38', '48') THEN 8
ELSE 9 END AS productLine
FROM Table AS a
) x
GROUP BY x.Id, x.pid) y
GROUP BY y.Id
HAVING COUNT(*) > 1
答案 1 :(得分:0)
Althoug我非常喜欢Rafał的解决方案,因为它为小组提供了数字,我想到了另一个更简单的解决方案,但是无法提前测试它。
SELECT distinct(id) FROM store a
WHERE 4 = (
SELECT COUNT(DISTINCT(pid))
FROM store
where (id = a.id AND (
pid in (1, 21, 31, 41) OR
pid in (2, 22, 32, 42)
)
)
)