首页 > 解决方案 > 用于标记表中此特定条件至少出现一次或多次的行的 Sql 语法

问题描述

我正在使用 SQL Server 2014,并且我有一个表 (t1),其中包含超过 25,000 行中的 6 个数字的列表。

t1 的摘录如下:

Id    F1   F2   F3   F4   F5   F6
1     5    11   15   21   30   36
2     8    10   21   25   32   39
3     10   18   23   27   28   32
...

我想写 2 个案例陈述来执行以下操作:

这是我期望的输出:

Id    F1   F2   F3   F4   F5   F6  LastDigit   CountLastDigit
1     5    11   15   21   30   36    Yes            4
2     8    10   21   25   32   39    No             0
3     10   18   23   27   28   32    Yes            2
...

我坚持编写 2 个案例陈述背后的逻辑。任何帮助,将不胜感激。

标签: sqlsql-servertsqlgroup-byunpivot

解决方案


这是一个有趣的问题。您可以通过横向连接来做到这一点。这个想法是将数字列转换为行,按最后一位聚合并仅保留最常出现的数字。然后你只需要添加一点条件逻辑:

select *
from mytable t
cross apply (
    select top (1) 
        case when count(*) = 1 then 'No' else 'Yes'    end LastDigit,
        case when count(*) = 1 then 0    else count(*) end CountLastDigit
    from (values(f1), (f2), (f3), (f4), (f5), (f6)) x(f)
    group by f % 10
    order by CountLastDigit desc
) z

DB Fiddle 上的演示

身份证 | F1 | F2 | F3 | F4 | F5 | F6 | 最后一位 | CountLastDigit
-: | -: | -: | -: | -: | -: | -: | :-------- | -------------:
 1 | 5 | 11 | 15 | 21 | 30 | 36 | 是 | 2
 2 | 8 | 10 | 21 | 25 | 32 | 39 | 没有 | 0
 3 | 10 | 18 | 23 | 27 | 28 | 30 | 是 | 2

如果您想对顶级关系的计数求和,则在子查询中需要多一层聚合:

select *
from mytable t
cross apply (
    select 
        max(LastDigit) LastDigit,
        sum(CountLastDigit) CountLastDigit
    from (
        select top (1) with ties
            case when count(*) = 1 then 'No' else 'Yes'    end LastDigit,
            case when count(*) = 1 then 0    else count(*) end CountLastDigit
        from (values(f1), (f2), (f3), (f4), (f5), (f6)) x(f)
        group by f % 10
        order by CountLastDigit desc
    ) z
) z


推荐阅读