T-Sql:选择至少两个字段匹配条件的行

时间:2016-01-26 10:39:24

标签: sql tsql

我有一张桌子,我们用主键和五个整数字段称它为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)。 / p>

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

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

3 个答案:

答案 0 :(得分:8)

您可以使用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

答案 1 :(得分:5)

虽然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,基本上每个数据库都可用。

答案 2 :(得分:2)

如果您的数据已标准化,这很容易解决 - 所以让我们使用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更好的名称来描述 这些数据(存储的数字和嵌入的数字)列名称)实际上是。