将自JOIN转换为PARTITION BY的SQL语法

时间:2018-02-11 13:44:53

标签: sql sql-server

我可以重写这个查询

查询1:

string s; 
cin >> s;

如下

QUERY2:

SELECT t1.*, COUNT(t2.t_Name) AS CountMatches
FROM
Table1 t1
LEFT OUTER JOIN
(SELECT * FROM Table1) t2
ON t1.[t_Area] = t2.[t_Area]
AND t1.[t_Name] = t2.[t_Name]
AND t2.[t_Date] < t1.[t_Date]
AND t2.[t_Value] = '1'
WHERE t1.[t_Date] = '2018-01-01'
GROUP BY t1.[t_Date], t1.[t_Area], t1.[t_Name], t1.[t_Length], t1.[t_Value]

我试图添加一个额外的术语,但在语法上挣扎

如何将以下字词添加到Query2 SELECT t2.* FROM ( SELECT t1.*, SUM(CASE WHEN t1.[t_Value] = '1' THEN 1 ELSE 0 END) OVER (PARTITION BY t1.[t_Area], t1.[t_Name] ORDER BY t1.[t_Date] ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS CountMatches FROM Table1 t1 ) t2 WHERE t2.[t_Date] = '2018-01-01'

给出所需结果的等效自连接查询如下

AND ABS(t1.[t_Length] - t2.[t_Length]) <= 1

示例SQLFiddle:http://sqlfiddle.com/#!18/f15ec/10

期望的输出: enter image description here

示例数据:

SELECT t1.*, COUNT(t2.t_Name) AS CountMatches
FROM
Table1 t1
LEFT OUTER JOIN
(SELECT * FROM Table1) t2
ON t1.[t_Area] = t2.[t_Area]
AND t1.[t_Name] = t2.[t_Name]
AND t2.[t_Date] < t1.[t_Date]
AND t2.[t_Value] = '1'
AND ABS(t1.[t_Length] - t2.[t_Length]) <= 1 --(Need this term as well)
WHERE t1.[t_Date] = '2018-01-01'
GROUP BY t1.[t_Date], t1.[t_Area], t1.[t_Name], t1.[t_Length], t1.[t_Value]

1 个答案:

答案 0 :(得分:3)

您正在混合来自&#34;当前&#34;行和&#34;之前&#34;窗口函数中的行。不幸的是,这无法表达。

在SQL Server中,您可以改为使用apply

SELECT t1.*, tt1.CountMatches
FROM table1 t1 OUTER APPLY
     (SELECT COUNT(*) as CountMatches
      FROM table1 tt1
      WHERE tt1.[t_Area] = t1.[t_Area] AND
            tt1.[t_Name] = t1.[t_Name] AND
            tt1.[t_Date] < t1.[t_Date] AND
            tt1.[t_Value] = '1' AND
            ABS(t1.[t_Length] - tt1.[t_Length]) <= 1 
     ) tt1
WHERE t1.[t_Date] = '2018-01-01';

就性能而言,这可以节省外部聚合。