有条件地处理多次出现的值

时间:2016-06-30 08:27:37

标签: sql sql-server sql-server-2008

我有一个查询,它将带有特定键的行映射到ID。

查询如下所示:

SELECT 
    ID, Note, Importdate, Group
FROM 
    SAP_OPListen2015 
INNER JOIN 
    (SELECT 
         Rechnnr, K, Aufttext, Betrag 
     FROM 
         SAP_OPListen2015 
     WHERE 
          ID = 75790) AS sq_Temp ON SAP_OPListen2015.Rechnnr = sq_Temp.Rechnnr 
                                 AND SAP_OPListen2015.K = sq_Temp.K 
                                 AND SAP_OPListen2015.Aufttext = sq_Temp.Aufttext 
                                 AND sq_Temp.Betrag = SAP_OPListen2015.Betrag 
ORDER BY 
    Importdate

执行返回以下行:

ID      NOTE    IMPORTDATE              GROUP
----------------------------------------------
75790   NULL    2016-05-30 00:00:00.000 NULL
76357   NULL    2016-05-30 00:00:00.000 G
74186   NULL    2016-04-30 00:00:00.000 E
72688   NULL    2016-03-30 00:00:00.000 NULL
71019   NULL    2015-11-30 00:00:00.000 NULL
69481   NULL    2015-10-31 00:00:00.000 NULL
68173   NULL    2015-09-30 00:00:00.000 NULL
67142   NULL    2015-05-31 00:00:00.000 NULL

您看到importdate(2016-05-30)发生了两次。我希望如果相同的日期发生两次,那么它应该只返回“Group”等于'G'的行。

有人知道怎么做吗?我几乎尝试了所有东西,但我意识到我缺乏SQL的语法知识。

提前致谢

编辑:

我想在这里看到的结果是:

ID      NOTE    IMPORTDATE              GROUP
----------------------------------------------
76357   NULL    2016-05-30 00:00:00.000 G
74186   NULL    2016-04-30 00:00:00.000 E
72688   NULL    2016-03-30 00:00:00.000 NULL
71019   NULL    2015-11-30 00:00:00.000 NULL
69481   NULL    2015-10-31 00:00:00.000 NULL
68173   NULL    2015-09-30 00:00:00.000 NULL
67142   NULL    2015-05-31 00:00:00.000 NULL

1 个答案:

答案 0 :(得分:0)

它是top-n-per-group查询的变体。

以下是使用ROW_NUMBER()执行此操作的一种方法。此函数将为每行分配一个数字。其PARTITION BY Importdate子句将为每个日期重新开始行号。它的ORDER BY子句会将[Group] = 'G'行放在分区的顶部,这些行会有rn = 1

如果您有两行或多行具有相同的Importdate[Group] = 'G',则未定义将选择哪一行。您可以向ORDER BY子句添加更多列(例如ID)以定义要选择的行。

WITH
CTE
AS
(
    SELECT 
        ID, Note, Importdate, Group
        ,ROW_NUMBER() OVER (PARTITION BY Importdate 
            ORDER BY CASE WHEN [Group] = 'G' THEN 0 ELSE 1 END) AS rn
    FROM 
        SAP_OPListen2015 
        INNER JOIN 
        (
            SELECT 
                Rechnnr, K, Aufttext, Betrag 
            FROM 
                SAP_OPListen2015 
            WHERE 
                ID = 75790
        ) AS sq_Temp 
            ON SAP_OPListen2015.Rechnnr = sq_Temp.Rechnnr 
            AND SAP_OPListen2015.K = sq_Temp.K 
            AND SAP_OPListen2015.Aufttext = sq_Temp.Aufttext 
            AND sq_Temp.Betrag = SAP_OPListen2015.Betrag 
)
SELECT
    ID, Note, Importdate, Group
FROM CTE
WHERE rn = 1
ORDER BY 
    Importdate
;