带条件的T-SQL OVER / PARTITION BY查询

问题描述 投票:2回答:6

我正在努力处理SQL查询,虽然我已经查看了许多类似的答案,但它们都不适合我的情况。我有一个数据集如下:

Date1       Amount 1    Index   Date2               Type Supplier
31/03/2018  410000.00   17      16/04/2018 06:27    102  A
31/03/2018  410000.00   17      16/04/2018 06:31    102  B
31/03/2018  400000.00   2       16/04/2018 06:37    102  A
31/03/2018  400000.00   2       16/04/2018 06:38    102  B
30/06/2018  0           20      04/07/2018 08:23    202  A
30/06/2018  0           20      04/07/2018 08:23    202  B
30/06/2018  412000.00   20      06/07/2018 12:46    102  A
30/06/2018  412000.00   20      06/07/2018 12:47    102  B
30/06/2018  442000.00   100     16/07/2018 06:27    102  A
30/06/2018  442000.00   100     16/07/2018 06:31    102  B

对于每个Date1,其中有多个行具有相同的Type,我只想要索引与最大Date2的索引匹配的行,所以我想要这个输出:

Date1       Amount 1    Index   Date2               Type Supplier
31/03/2018  400000.00   2       16/04/2018 06:37    102  A
31/03/2018  400000.00   2       16/04/2018 06:38    102  B
30/06/2018  0           20      04/07/2018 08:23    202  A
30/06/2018  0           20      04/07/2018 08:23    202  B
30/06/2018  442000.00   100     16/07/2018 06:27    102  A
30/06/2018  442000.00   100     16/07/2018 06:31    102  B

我认为应该可以使用某种形式的条件MAX()OVER(PARTITION BY),但对于我的生活,我无法弄清楚如何做到这一点。

sql sql-server window-functions
6个回答
2
投票

LAST_VALUE (Transact-SQL)解析函数与子查询一起使用。 以下工作示例适用于Oracle(我更喜欢Oracle,因为我总是在SQLServer上转换日期时遇到问题),但查询的想法是一样的,语法也是一样的: 演示:http://www.sqlfiddle.com/#!4/004ce7/19

SELECT * FROM (
   SELECT t.* ,
     last_value( "INDEX" ) OVER 
        ( partition by date1, "TYPE" order by date2
          ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) xx
   FROM table1 t
) x
WHERE xx = "INDEX"
ORDER BY date1;

|                DATE1 | AMOUNT1 | INDEX |                 DATE2 | TYPE | SUPPLIER |  XX |
|----------------------|---------|-------|-----------------------|------|----------|-----|
| 2018-03-31T00:00:00Z |  400000 |     2 | 2018-04-16 06:37:00.0 |  102 |        A |   2 |
| 2018-03-31T00:00:00Z |  400000 |     2 | 2018-04-16 06:38:00.0 |  102 |        B |   2 |
| 2018-06-30T00:00:00Z |  442000 |   100 | 2018-07-16 06:27:00.0 |  102 |        A | 100 |
| 2018-06-30T00:00:00Z |  442000 |   100 | 2018-07-16 06:31:00.0 |  102 |        B | 100 |
| 2018-06-30T00:00:00Z |       0 |    20 | 2018-07-04 08:23:00.0 |  202 |        B |  20 |
| 2018-06-30T00:00:00Z |       0 |    20 | 2018-07-04 08:23:00.0 |  202 |        A |  20 |

1
投票

使用row_number()

SELECT [Date1],[Amount 1],[Index],[Date2],[Type],[Supplier]
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY [Date1] ORDER BY [Date2] DESC) AS rn
    FROM tablename
) a
WHERE a.rn in( 1,2)

1
投票

试试这个

;WITH CTE
AS
(
    SELECT
        *,
        MxDt =ROW_NUMBER() OVER(PARTITION BY Date1,[Type] ORDER BY Date2 DESC)
        FROM YourTableName
)
SELECT
    *
    FROM CTE C1
        WHERE EXISTS
        (
            SELECT
                1
                FROM CTE C2
                    WHERE [Index] = C1.[Index]
                        AND [Type]= C1.[Type]
                        AND C2.MxDt =1
        )

1
投票

我想这就是你想要的。注意使用ROW_NUMBER而不是RANK - RANK会产生多个值1,其中Date2是相同的,ROW_NUMBER将为rn产生唯一的增量值:

SELECT
    [Date1],
    [Amount 1],
    [Index],
    [Date2],
    [Type],
    [Supplier]
FROM my_table
INNER JOIN (
    SELECT
        [Index],
        [Type],
        ROW_NUMBER() OVER (PARTITION BY [Date1], [Type] ORDER BY [Date2] DESC) AS rn
    FROM my_table
) AS subquery
    ON subquery.rn = 1
    AND subquery.[Index] = my_table.[Index]
    AND subquery.[Type] = my_table.[Type]

0
投票

子查询对数据进行排序,以便控制索引的行对于每个日期和类型分组始终为row_no。外部查询返回具有相同date1,type,index组合的所有行,但忽略其他行

Select *
From Data D
    inner join SortedData S on S.Date1 = A.Date1 
          and S.Type = A.Type 
          and S.RowNo = 1 
          and D.Index = A.index

(Select Date1, Type, Index, row_Number() over (Partition by Date1, Type ORDER BY Date2 DESC) as RowNo From Data) SortedData

0
投票

您可以使用相关子查询:

select t.*
from table t
where Index = (select top (1) t1.Index
               from table t1
               where t1.Date1 = t.Date1 and t1.type = t.type
               order by t1.date2 desc
              );   
© www.soinside.com 2019 - 2024. All rights reserved.