Подсчет текстовых значений по столбцам в SQL с использованием выражений CASE WHEN - PullRequest
1 голос
/ 20 марта 2020

У меня есть таблица, в которой я определяю, существует ли идентификационный номер человека в нескольких базах данных. Если идентификатор существует только в одной базе данных, я хотел бы добавить еще один столбец, который помечает человека как «УНИКАЛЬНЫЙ»; в противном случае он должен быть помечен как «НЕ УНИКАЛЬНЫЙ».

Мой запрос на данный момент настроен так:

/* CTE that creates a long column of all distinct PersonID's across three databases */

WITH cte as
(SELECT DISTINCT t1.*
FROM 
(SELECT PersonID FROM DB_1.dbo.Persons
 UNION
 SELECT PersonID FROM DB_2.dbo.Persons
 UNION
 SELECT PersonID FROM DB_3.dbo.Persons)
t1)

/* Use CASE WHEN statements to check if Person exists in three other tables in DB_1, DB_2, and DB_3 */ 

SELECT PersonID,
    CASE WHEN PersonID IN (SELECT PersonID FROM DB_1.dbo.Table_1
                            UNION
                            SELECT PersonID FROM DB_1.dbo.Table_2
                            UNION 
                            SELECT PersonID FROM DB_1.dbo.Table_3)
    THEN 'TRUE'
    ELSE 'FALSE'
    END AS IN_DB_1,

    CASE WHEN PersonID IN (SELECT PersonID FROM DB_2.dbo.Table_1
                            UNION
                            SELECT PersonID FROM DB_2.dbo.Table_2
                            UNION 
                            SELECT PersonID FROM DB_2.dbo.Table_3)
    THEN 'TRUE'
    ELSE 'FALSE'
    END AS IN_DB_2,

    CASE WHEN PersonID IN (SELECT PersonID FROM DB_3.dbo.Table_1
                            UNION
                            SELECT PersonID FROM DB_3.dbo.Table_2
                            UNION 
                            SELECT PersonID FROM DB_3.dbo.Table_3)
    THEN 'TRUE'
    ELSE 'FALSE'
    END AS IN_DB_3

FROM cte

Результаты выглядят так:

PersonID   IN_DB_1    IN_DB_2    IN_DB_3
---------|----------|----------|----------|
001         TRUE       FALSE      FALSE
002         FALSE      TRUE       TRUE
003         TRUE       FALSE      FALSE
004         FALSE      TRUE       FALSE
005         TRUE       FALSE      TRUE

Как видно, номера PersonID 001, 003 и 004 появляются только в одной базе данных. Я хотел бы добавить пятый столбец с именем «PID_UNIQUE», который подсчитывает количество текстовых значений «ИСТИНА» в столбцах и указывает, является ли человек уникальным.

Он должен выглядеть следующим образом:

PersonID   IN_DB_1    IN_DB_2    IN_DB_3    PID_UNIQUE
---------|----------|----------|----------|-----------|
001         TRUE       FALSE      FALSE      UNIQUE
002         FALSE      TRUE       TRUE      NOT UNIQUE
003         TRUE       FALSE      FALSE      UNIQUE
004         FALSE      TRUE       FALSE      UNIQUE
005         TRUE       FALSE      TRUE      NOT UNIQUE

Я предполагаю, что это будет настроено с использованием другого выражения CASE WHEN. Я немного застрял в том, как я мог бы написать это, чтобы сосчитать через три столбца "IN_DB_no".

Я попробовал это:

CASE WHEN COUNT('TRUE') = 1
THEN 'UNIQUE'
ELSE 'NOT UNIQUE'
END AS PID_UNIQUE

Однако он вернул столбец, в котором все записи были уникальными, а это не то, что мне нужно.

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

У меня есть таблица, в которой я определяю, существует ли идентификационный номер человека в нескольких базах данных.

Ваш пример запроса ссылается на гораздо больше таблиц, чем это предполагает. Следовательно, это кажется намного более сложным, чем необходимо.

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

SELECT PersonID, MAX(in_1), MAX(in_2), MAX(in_3),
       (CASE WHEN MAX(in_1) + MAX(in_2) + MAX(in_3) = 1 THEN 'UNIQUE'
             ELSE 'NOT UNIQUE'
        END) as pid_Unique
FROM ((SELECT DISTINCT PersonID, 1 as in_1, 0 as in_2, 0 as in_3
       FROM DB_1.dbo.Persons
      ) UNION ALL
      (SELECT DISTINCT PersonID, 0 as in_1, 1 as in_2, 0 as in_3
       FROM DB_2.dbo.Persons
      ) UNION ALL
      (SELECT DISTINCT PersonID, 0 as in_1, 0 as in_2, 1 as in_3
       FROM DB_3.dbo.Persons
      )
     ) p
GROUP BY PersonId;
0 голосов
/ 20 марта 2020

Я нашел решение, которое работает для меня, используя оператор CROSS APPLY вместе с выражением CASE / WHEN.

По сути, я добавил дополнительный столбец в таблицу, которую я уже сделали.

Запрос выглядел так:

SELECT * FROM My_New_DB.dbo.My_New_Tbl

CROSS APPLY (
              SELECT CASE WHEN 1 = (SELECT COUNT(*)
              FROM (VALUES (IN_DB_1), (IN_DB_2), (IN_DB_3)) C (Val)
              WHERE Val = 'TRUE')
              THEN 'UNIQUE'
              ELSE 'NOT UNIQUE'
              END AS UNIQUE_ID
                               ) A

Проще говоря, когда 1 = 1, он уникален.

...