Reputation: 510
I've got a table, let's call it values
with a primary key and five integer fields, like this:
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
Now I need to select all rows where at least any two of the five value fields got the value 4. So the result set should contain the first row (id=1) and the last row (id=4).
I started with a simple OR condition but there are too many combinations. Then I tried a sub-select with HAVING and COUNT but no success.
Any Ideas how to solve this?
Upvotes: 0
Views: 2138
Reputation: 1271151
Although cross apply
is fast, it might be marginally faster to simply use 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;
I will also note that case
is ANSI standard SQL and available in basically every database.
Upvotes: 6
Reputation: 239824
This is trivial to solve if your data is normalized - so lets use UNPIVOT
to normalize the data and then solve it:
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
Results:
id
-------
1
4
Of course, you can probably come up with better names than valness
and colness
that describes what these pieces of data (the numbers being stored and the numbers embedded in the column names) actually are.
Upvotes: 2
Reputation: 72225
You can use VALUES
to construct an inline table containing your fields. Then query this table to get rows having at least two fields equal to 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
Upvotes: 9