从JOIN查询中查找MAX值

时间:2017-10-24 06:57:20

标签: sql-server sql-server-2008 query-optimization

我有以下两个表:

表#USER

SELECT *
INTO #USER
FROM (
    SELECT 'A.2017.JAN' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.JAN' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.FEB' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.FEB' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'Kate' AS [Name], 'Blue' AS [Surname]
) A

表#KSCEN

SELECT *
INTO #KSCEN
FROM (
    SELECT 'A.2017.JAN' AS [ID], 6 AS [SEQ] UNION ALL
    SELECT 'A.2017.FEB' AS [ID], 7 AS [SEQ] UNION ALL
    SELECT 'A.2017.MAR' AS [ID], 8 AS [SEQ] UNION ALL
    SELECT 'A.2017.APR' AS [ID], 9 AS [SEQ] UNION ALL
    SELECT 'A.2017.MAY' AS [ID], 10 AS [SEQ]
) A

我的目标是找到带有MAX SEQ的#KSCEN元素,该元素在表#USER中至少使用过一次。 我得到了以下子查询和LEFT JOIN:

SELECT [ID]
FROM #KSCEN
WHERE [SEQ] = (SELECT MAX(B.[SEQ]) FROM #USER A LEFT JOIN #KSCEN B ON A.[KSCEN]=B.[ID])

这可行,但考虑到表#USER,在我的情况下,包含超过30,000,000行,因此解决查询的速度不是很快,因为系统需要连接每一行然后找到MAX。

有没有更有效的方法来解决我的问题?

1 个答案:

答案 0 :(得分:0)

我会避免你在where子句中使用import bcrypt。当from / where子句的每一行都针对MAX()计算进行测试时,它产生一个“按行划分”的效果,每行一个新查询。

如果没有使用真实表格或执行计划的好处,我建议如下:

您可以在SQL Fiddle

尝试

查询1

correlated subquery

<强> Results

with tUSER as 
(
    SELECT 'A.2017.JAN' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.JAN' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.FEB' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.FEB' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL
    SELECT 'A.2017.MAR' AS [KSCEN], 'Kate' AS [Name], 'Blue' AS [Surname]
) 
, tKSCEN as  (
    SELECT 'A.2017.JAN' AS [ID], 6 AS [SEQ] UNION ALL
    SELECT 'A.2017.FEB' AS [ID], 7 AS [SEQ] UNION ALL
    SELECT 'A.2017.MAR' AS [ID], 8 AS [SEQ] UNION ALL
    SELECT 'A.2017.APR' AS [ID], 9 AS [SEQ] UNION ALL
    SELECT 'A.2017.MAY' AS [ID], 10 AS [SEQ]
)
SELECT U.[KSCEN], MAX(K.[SEQ])  max_seq
FROM tUSER U 
LEFT JOIN tKSCEN K ON U.[KSCEN]=K.[ID]
GROUP BY U.[KSCEN]
;