基于行号(T-SQL)的条件选择

时间:2018-03-07 09:57:55

标签: sql tsql select window-functions

我是一名数据分析师,只是潜入SQL深度。请原谅我,如果我在这里陈述的问题没有明确表达,我愿意​​提出改善问题制定技巧的建议!

所以我有这个表,但它有一些双重信息(参见-DATASET& --VALUES,PersonID = 2,RowNr = 1& 2)。我想过滤掉double的行,以便语句显示:只选择RowNr 1中的CreationID为RowID 2中的CreationID = RowID 2中的CreationID,行按PersonID和StartDate分组。

这是我的脚本,带有所需的结果:

-- DATASET
CREATE TABLE Conditional (
    PersonID int
    , StartDate date
    , CreationDate date
    , RowNr int
);

-- VALUES
INSERT INTO Conditional (PersonID, StartDate, CreationDate, RowNr)
VALUES
    ('1', '20151201', '20151220', '1'),
    ('1', '20151201', '20151220', '2'),
    ('2', '20160303', '20160304', '1'),
    ('2', '20160303', '20160401', '2');

-- DESIRED RESULT
INSERT INTO Conditional (PersonID, StartDate, CreationDate, RowNr)
VALUES
    ('1', '20151201', '20151220', '1'),
    ('2', '20160303', '20160304', '1'),
    ('2', '20160303', '20160401', '2');

3 个答案:

答案 0 :(得分:0)

您希望对记录进行排名,并仅显示排名最高的记录。为此,请对RANK rownrpersonidstartdate申请creationdate。然后使用限制子句保持排名#1的行,在标准SQL中为FETCH FIRST n ROWS WITH TIES

select *
from conditional
order by rank() over (partition by personid, startdate, creationdate order by rownr)
fetch first 1 row with ties;

您尚未标记自己的DBMS。其limit子句可能与标准SQL不同。

答案 1 :(得分:0)

您所展示的是插入语句,因此在进入SQL数据库之前。我的回答基于你想要在SQL中解决问题的前提。

您有不同的选择:

  1. PersonID + StartDate + CreationDate 上创建一个唯一键。尝试插入副本时,您将收到错误。

  2. 保留所有数据,根据需要将其过滤到Select-Events。 (见Thorsten Kettner的回答)

  3. 插入后清理并删除重复项:See this Question

  4. 您可能还想查看 RowNr 字段 - 可能是多余的,最好在您的选择中动态创建。

答案 2 :(得分:0)

如果在SQL Server或Oracle SQL上:

WITH DuplicationRanking AS
(
    SELECT
        D.*,
        ROW_NUMBER() OVER (
            PARTITION BY
                PersonID, -- Your unique columns here
                StartDate,
                CreationDate
            ORDER BY
                RowNr ASC) AS DuplicationRanking
        FROM
            Conditional AS D
)
SELECT
    D.*
FROM
    DuplicationRanking AS D
WHERE
    D.DuplicationRanking = 1
-- You can GROUP BY here

一般情况下,使用上述列中的GROUP BY

SELECT
    C.*
FROM
    Conditional AS C
    INNER JOIN
        (SELECT
            PersonID,
            StartDate,
            RowNr = MIN(RowNr)
        FROM
            Conditional
        GROUP BY
            PersonID,
            StartDate) AS D ON
        C.PersonID = D.PersonID AND
        C.StartDate = D.StartDate AND
        C.RowNr = D.RowNr
相关问题