【问题标题】:function that allows grouping of rows允许对行进行分组的函数
【发布时间】:2019-12-20 21:38:17
【问题描述】:

我正在使用 SQL Server Management Studio 2012。我从下面显示的查询中得到了类似的输出。我想从查询中删除有 2 份合同的人。

Select
Row_Number() over (partition by ID ORDER BY  ContractypeDescription DESC) as [Row_Number],
Name,
ContractDescription,
Role

From table    

输出

Row_Number   ID     Name     Contract Description   Role
    1       1234    Mike          FullTime          Admin
    2       1234    Mike          Temp              Manager
    1       5678    Dave          FullTime          Admin
    1       9785    Liz           FullTime          Admin       

我想看什么

 Row_Number   ID    Name     Contract Description   Role
    1       5678    Dave          FullTime          Admin
    1       9785    Liz           FullTime          Admin

是否有一个函数而不是 Row_Number 允许您将行分组在一起,以便我可以使用类似“其中 Row_Number 不像 1 和 2”之类的东西?

【问题讨论】:

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

你可以使用HAVING作为

SELECT ID,
       MAX(Name) Name,
       MAX(ContractDescription) ContractDescription,
       MAX(Role) Role
FROM t
GROUP BY ID
HAVING COUNT(*) = 1;

Demo

【讨论】:

  • 感谢大家的回答,他们都工作但决定采用这个答案,因为它更容易插入我的查询
【解决方案2】:

试试这个:

select * from (
Select
Count(*) over (partition by ID ) as [Row_Number],
Name,
ContractDescription,
Role
From table 
)t  where [Row_Number] = 1

【讨论】:

    【解决方案3】:

    你可以勾选这个选项-

    SELECT * 
    FROM table
    WHERE ID IN
    (
        SELECT ID
        FROM table
        GROUP BY ID
        HAVING COUNT(*) = 1
    )
    

    【讨论】:

      【解决方案4】:

      您可以使用CTE 来获取仅获得一份合同的人的所有ID,然后将CTE 的结果与您的表连接起来。

      ;with cte as (
              select
                  id
                  ,COUNT(id) as no
              from @tbl
              group by id
              having COUNT(id) = 1
          )
          select
              t.id
              ,t.name
              ,t.ContractDescription
              ,t.role
          from @tbl t
          inner join cte
              on t.id = cte.id
      

      【讨论】:

        【解决方案5】:

        基本上你需要those record who have exactly one contract

        只是扩展你的脚本,(我的脚本没有经过测试)

        ;with CTE as
            (
            Select
            Row_Number() over (partition by ID ORDER BY  ContractypeDescription DESC) as [Row_Number],
            Name,
            ContractDescription,
            Role
        
            From table    
            )
        
            select * from CTE c where [Row_Number]=1
            and not exists(select 1 from CTE c1 where c.id=c1.id and c1.[Row_Number]>1 )
        

        【讨论】:

          【解决方案6】:

          是否有一个函数而不是 Row_Number 可以让您分组 行在一起,这样我就可以使用类似 'where Row_Number not 像 1 和 2'?

          您可以使用带窗口的COUNT()。关键是OVER() 子句。

          ;WITH WindowedCount AS
          (
              SELECT
                  T.*,
                  WindowCount = COUNT(1) OVER (PARTITION BY T.ID)
              FROM
                  YourTable AS T
          )
          DELETE W FROM
              WindowedCount AS W
          WHERE
              W.WindowCount > 1
          

          COUNT() 将计算每个不同ID 的行数,因此如果相同的ID 出现在 2 行或更多行中,这些行将被删除。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-02
            相关资源
            最近更新 更多