【问题标题】:T-Sql: Select Rows where at least two fields matches conditionT-Sql:选择至少两个字段匹配条件的行
【发布时间】:2016-01-26 19:56:09
【问题描述】:

我有一个表,我们称之为values,有一个主键和五个整数字段,如下所示:

id  val1  val2  val3  val4  val5
1    4     3     4     5     3
2    2     3     2     2     2
3    5     4     1     3     3
4    1     4     3     4     4

现在我需要选择所有五个值字段中至少有两个值为 4 的行。因此结果集应该包含第一行 (id=1) 和最后一行 (id=4)。

我从一个简单的 OR 条件开始,但组合太多。然后我尝试使用 HAVING 和 COUNT 进行子选择,但没有成功。

任何想法如何解决这个问题?

【问题讨论】:

    标签: sql tsql


    【解决方案1】:

    您可以使用VALUES 构建包含您的字段的内联表。然后查询这个表,得到至少有两个字段等于 4 的行:

    SELECT *
    FROM mytable
    CROSS APPLY (
      SELECT COUNT(*) AS cnt
      FROM (VALUES (val1), (val2), (val3), (val4), (val5)) AS t(v)
      WHERE t.v = 4) AS x
    WHERE x.cnt >= 2  
    

    Demo here

    【讨论】:

    • 很好的解决方案。我会选择这种方式,因为 CROSS APPLY 对我来说比 UNPIVOT 更熟悉。谢谢!
    【解决方案2】:

    虽然cross apply 很快,但简单地使用case 可能会稍微快一些:

    select t.*
    from t
    where ((case when val1 = 4 then 1 else 0 end) +
           (case when val2 = 4 then 1 else 0 end) +
           (case when val3 = 4 then 1 else 0 end) +
           (case when val4 = 4 then 1 else 0 end) +
           (case when val5 = 4 then 1 else 0 end)
          ) >= 2;
    

    我还要注意,case 是 ANSI 标准 SQL,基本上在每个数据库中都可用。

    【讨论】:

      【解决方案3】:

      如果您的数据被规范化,这很容易解决 - 所以让我们使用UNPIVOT 来规范化数据然后解决它:

      declare @t table (id int not null, val1 int not null, val2 int not null,
                        val3 int not null, val4 int not null, val5 int not null)
      insert into @t(id,val1,val2,val3,val4,val5) values
      (1,4,3,4,5,3),
      (2,2,3,2,2,2),
      (3,5,4,1,3,3),
      (4,1,4,3,4,4)
      
      select
          id
      from
          @t t
              unpivot
          (valness for colness in (val1,val2,val3,val4,val5)) r
      group by id
      having SUM(CASE WHEN valness=4 THEN 1 ELSE 0 END) >= 2
      

      结果:

      id
      -------
      1
      4
      

      当然,您可能会想出比 valnesscolness 更好的名称来描述什么这些数据(存储的数字和嵌入列名中的数字)实际上是。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-12
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        • 2016-11-28
        • 1970-01-01
        相关资源
        最近更新 更多