SQL (Красное смещение): Найдите, встречается ли определенное значение более одного раза в нескольких столбцах

#sql #amazon-redshift

Вопрос:

Допустим, у меня есть 5 столбцов, которые могут содержать одно и то же значение. Я хочу вычислить новый столбец, который сообщит мне, встречается ли определенное значение более одного раза. Пример желаемых результатов в различных ситуациях:

Я хочу просканировать все строки, содержащие хотя бы одну из значений «X»:

ID A B C D E Результат
1 X Y X Z Правда
2 X Y Y Z Ложный
3 Y Y Z Ложный
4 X X Y X Правда

«Случай, когда» теоретически был бы возможен, но перебор всех вариантов невыполним: для этого требуется слишком много комбинаций. Может быть, какой-то внутренний вопрос?

Редактировать:

Я действительно нашел решение, сделав объединение. Но ответ Гордона Линоффа гораздо более ясен.

 select id,
case when b.num_X > 1 then True else False end as result 
from foo f
join (
    select a b c d e as num_X from (
        select 
        id,
        case when A = 'X' then 1 else 0
        end as a,
        case when B = 'X' then 1 else 0
        end as b,
        case when C = 'X' then 1 else 0
        end as c,
        case when D = 'X' then 1 else 0
        end as d,
        case when E = 'X' then 1 else 0
        end as e
        from foo
    )
) b on f.id = b.id
 

Ответ №1:

Один из способов-просто сосчитать их:

 select t.*,
       ( (a = 'X')::int   (b = 'X')::int   (c = 'X')::int   (d = 'X')::int   (e = 'X')::int) ) >= 2 as result
from t;
 

Если столбцы могут содержать NULL значения, то вам нужно обратить на это внимание. Один из методов заключается в использовании coalesce() приведенного выше выражения:

        ( (coalesce(a, '') = 'X')::int  
         (coalesce(b, '') = 'X')::int  
         (coalesce(c, '') = 'X')::int  
         (coalesce(d, '') = 'X')::int  
         (coalesce(e, '') = 'X')::int)
       ) >= 2 as result
 

Комментарии:

1. Я знал, что это будет просто, а теперь чувствую себя глупо. Все еще что-то новенькое, и я не знал, что ты так умеешь считать.. Спасибо!