SQL Server: несколько строк ИСТИНА / ЛОЖЬ в одну строку БИТ с условием ИСТИНА / ЛОЖЬ - PullRequest
0 голосов
/ 11 декабря 2019

Я застрял с кодом в T-SQL. Я попытался обновить глобальный результат из нескольких строк истина / ложь только с одним условием, если любое из всех значений из «столбца значений» истинно, тогда глобальное значение истинно. Столбцы REF и REF_GLOBAL одинаковы.

Как в этом примере:

Здесь есть только один REF, но я получил что-то вроде REF1, REF2, REF3 и т.д ...

SOURCE_TABLE:

+----+-------+-------+-------+
|REF |VALUE_1|VALUE_2|VALUE_3|
+----+-------+-------+-------+      
|REF1| FALSE | TRUE  | FALSE |
|REF1| TRUE  | FALSE | FALSE |
|REF1| TRUE  | FALSE | FALSE |
|REF1| FALSE | FALSE | FALSE |
+----+-------+-------+-------+  

GLOBAL_TABLE :

+-----------+-------+-------+-------+
|REF_GLOBAL |VALUE_1|VALUE_2|VALUE_3|
+-----------+-------+-------+-------+
|REF1_GLOBAL|   1   |   1   |   0   |
+-----------+-------+-------+-------+

Когда есть только одна строка, это легко:

UPDATE T1
SET T1.VALUE_1 = (CASE WHEN T2.VALUE_1 = 'TRUE' THEN 1 ELSE 0 END),
    T1.VALUE_2 = (CASE WHEN T2.VALUE_2 = 'TRUE' THEN 1 ELSE 0 END),
    T1.VALUE_3 = (CASE WHEN T2.VALUE_3 = 'TRUE' THEN 1 ELSE 0 END)
FROM GLOBAL_TABLE T1, SOURCE_TABLE T2
WHERE T1.REF = T2.REF_GLOBAL

Но я застреваю, когда хочу сделать это из несколькихзначение к одному значению, учитывая, что если хотя бы одно значение истинно, то глобальный результат равен 1.

Я уверен, что это связано с выражением if с предложением any, но даже после чтения несколькихДокументация и форум Я не могу найти, как с этим справиться.

Надеюсь, вы мне поможете.

Ответы [ 3 ]

1 голос
/ 11 декабря 2019

Вариант ответа Тима Бигелайзена: Вы можете воспользоваться bit значениями типа обработки данных 'TRUE' и 'FALSE' как 1 и 0 соответственно. Как указал forpas, агрегация в bit не поддерживается, поэтому требуется дополнительная cast.

select Ref + '_GLOBAL' as Ref_Global,
  Max( Cast( Cast( Value_1 as Bit ) as Int ) ) as Value_1,
  Max( Cast( Cast( Value_2 as Bit ) as Int ) ) as Value_2,
  Max( Cast( Cast( Value_3 as Bit ) as Int ) ) as Value_3
  from Source_Table
  group by Ref

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

В сторону: Для тех, кто предпочитает запутывание, можно использовать правила для precencece типа данных и использовать Max( Cast( Value_1 as Bit ) + 0 ) ), чтобы скрыть намерение. Это не рекомендуется для поддерживаемого кода.

0 голосов
/ 11 декабря 2019

Может быть, EXISTS работает лучше в этом случае, потому что он вернется, как только обнаружит «ИСТИНА»:

UPDATE GLOBAL_TABLE 
SET
  VALUE_1 = CASE 
    WHEN EXISTS (SELECT 1 FROM SOURCE_TABLE WHERE VALUE_1 = 'TRUE' AND REF_GLOBAL = REF + '_GLOBAL') THEN 'TRUE' 
    ELSE 'FALSE' 
  END,
  VALUE_2 = CASE 
    WHEN EXISTS (SELECT 1 FROM SOURCE_TABLE WHERE VALUE_2 = 'TRUE' AND REF_GLOBAL = REF + '_GLOBAL') THEN 'TRUE' 
    ELSE 'FALSE' 
  END,
  VALUE_3 = CASE 
    WHEN EXISTS (SELECT 1 FROM SOURCE_TABLE WHERE VALUE_3 = 'TRUE' AND REF_GLOBAL = REF + '_GLOBAL') THEN 'TRUE' 
    ELSE 'FALSE' 
  END  
WHERE REF_GLOBAL = 'REF1_GLOBAL';

См. Демоверсию . Результаты:

> REF_GLOBAL  | VALUE_1 | VALUE_2 | VALUE_3
> :---------- | :------ | :------ | :------
> REF1_GLOBAL | True    | True    | False  
0 голосов
/ 11 декабря 2019

Я предлагаю даже не использовать глобальную таблицу, а вместо этого просто использовать условное агрегирование для генерирования вывода, который вы хотите увидеть:

SELECT
    REF + '_GLOBAL' AS REF_GLOBAL,
    CASE WHEN COUNT(CASE WHEN VALUE_1 = 'TRUE' THEN 1 END) > 0 THEN 1 ELSE 0 END AS VALUE_1,
    CASE WHEN COUNT(CASE WHEN VALUE_2 = 'TRUE' THEN 1 END) > 0 THEN 1 ELSE 0 END AS VALUE_2,
    CASE WHEN COUNT(CASE WHEN VALUE_3 = 'TRUE' THEN 1 END) > 0 THEN 1 ELSE 0 END AS VALUE_3
FROM SOURCE_TABLE
GROUP BY
    REF
ORDER BY
    REF;

screen capture from demo below

Демонстрация

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

Одна из причин отказа от ведения глобальной таблицы состоит в том, что ее данные являются просто производной от исходной таблицы. Теоретически, каждый раз, когда данные исходной таблицы изменяются, агрегаты в глобальной таблице становятся устаревшими, и, возможно, их придется обновлять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...