Я пытаюсь объединить три таблицы и получить результаты, однако одна из таблиц имеет несколько event_code для одного и того же CSO_Item_key, что приводит к дублированию записей. Обратите внимание, что мой источник - Vertica, а Target - SQL-сервер. Я пробовал разные вещи и подходы к XML, но не работаю с Vertica; он говорит неверный синтаксис XML. Есть ли другое решение
Таблица 1
Entry Date Cso Item Key Fail Code
8/1/2018 4:28 BLXB796201 CSL120
8/1/2018 4:40 BLXB799101 CLL250
8/1/2018 4:55 BLXB803001 CMS130
8/1/2018 5:08 BLXB806201 CNE100
Таблица 2
Cso Item Key Event Code
BLXB796201 GTS
BLXB796201 LC28
BLXB796201 SDR4
BLXB799101 GTS
BLXB799101 LC28
BLXB799101 SDR4
BLXB803001 GTS
BLXB803001 LC28
BLXB803001 SDR4
BLXB806201 GTS
BLXB806201 LC28
BLXB806201 SDR4
Таблица 3
Fail Code Desc
CSL120 Bad Part
CLL250 Unit Scrapped
CNE100 OS Reinstall
CBN101 NTF
Ожидаемый результат:
Entry_Date Cso_Item_Key Fail_Code Desc Event_Code
8/1/2018 4:28 BLXB796201 CSL120 Bad Part GTS,LC28,SDR4
8/1/2018 4:40 BLXB799101 CLL250 Unit Scrapped GTS,LC28,SDR4
8/1/2018 4:55 BLXB803001 CMS130 Null GTS,LC28,SDR4
8/1/2018 5:08 BLXB806201 CNE100 OS Reinstall GTS,LC28,SDR4
Скриншот данных:
Я использую 2016
Одно из единственных решений, которые я видел для этого, - это расширение strings_package, которое можно найти здесь на github. С его помощью вы можете использовать функцию group_concat следующим образом:
-- get a list of nodes
select group_concat(node_name) over () from nodes;
-- nodes with storage for a projection
select schema_name,projection_name,
group_concat(node_name) over (partition by schema_name,projection_name)
from (select distinct node_name,schema_name,projection_name from storage_containers) sc order by schema_name, projection_name;
Это попытка сделать все это в SQL - немного обман, поскольку я полагаюсь на тот факт, что Table_2 всегда имеет 3 разных кода событий для каждого ключа CSO Item.
Если это не так, вам придется добавить несколько строк - до максимального количества кодов событий на ключ элемента CSO в индексную таблицу i
, которую я создаю как выражение общей таблицы, и вам придется ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к этой таблице i
к tb2
и добавьте в выражение некоторую логику обработки NULL, например: ||','||MAX(CASE i.i WHEN 2 THEN event_code END)
, чтобы объединить пустую строку, когда event_code
в выражении имеет значение NULL.
Но в противном случае - с вашим вводом (который вы должны исключить из запроса, когда вы действительно его используете), это может выглядеть так:
WITH
-- your input, don't use in real query ...
tb1(Entry_Date,Cso_Item_Key,Fail_Code) AS (
SELECT TIMESTAMP '8/1/2018 4:28','BLXB796201','CSL120'
UNION ALL SELECT TIMESTAMP '8/1/2018 4:40','BLXB799101','CLL250'
UNION ALL SELECT TIMESTAMP '8/1/2018 4:55','BLXB803001','CMS130'
UNION ALL SELECT TIMESTAMP '8/1/2018 5:08','BLXB806201','CNE100'
)
,
tb2(Cso_Item_Key,Event_Code) AS (
SELECT 'BLXB796201','GTS'
UNION ALL SELECT 'BLXB796201','LC28'
UNION ALL SELECT 'BLXB796201','SDR4'
UNION ALL SELECT 'BLXB799101','GTS'
UNION ALL SELECT 'BLXB799101','LC28'
UNION ALL SELECT 'BLXB799101','SDR4'
UNION ALL SELECT 'BLXB803001','GTS'
UNION ALL SELECT 'BLXB803001','LC28'
UNION ALL SELECT 'BLXB803001','SDR4'
UNION ALL SELECT 'BLXB806201','GTS'
UNION ALL SELECT 'BLXB806201','LC28'
UNION ALL SELECT 'BLXB806201','SDR4'
)
,
tb3(Fail_Code,Descr) AS (
SELECT 'CSL120','Bad Part'
UNION ALL SELECT 'CLL250','Unit Scrapped'
UNION ALL SELECT 'CNE100','OS Reinstall'
UNION ALL SELECT 'CBN101','NTF'
)
-- real WITH clause starts here - and table "i" can contain more than 3 rows..
,
i(i) AS (
SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
)
,
tb2_w_i AS (
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY cso_item_key ORDER BY event_code) AS i
FROM tb2
)
,
tb2_pivot AS (
SELECT
cso_item_key
, MAX(CASE i.i WHEN 1 THEN event_code END)
||','||MAX(CASE i.i WHEN 2 THEN event_code END)
||','||MAX(CASE i.i WHEN 3 THEN event_code END)
AS event_codes
FROM tb2_w_i JOIN i USING(i)
GROUP BY 1
)
SELECT
entry_date
, tb1.cso_item_key
, tb1.fail_code
, descr
, event_codes
FROM tb1
JOIN tb2_pivot USING(cso_item_key)
LEFT JOIN tb3 USING(fail_code)
;
Результат (мой NULLSTRING - прочерк ..)
entry_date |cso_item_key|fail_code|descr |event_codes
2018-08-01 04:28:00|BLXB796201 |CSL120 |Bad Part |GTS,LC28,SDR4
2018-08-01 04:40:00|BLXB799101 |CLL250 |Unit Scrapped|GTS,LC28,SDR4
2018-08-01 04:55:00|BLXB803001 |CMS130 |- |GTS,LC28,SDR4
2018-08-01 05:08:00|BLXB806201 |CNE100 |OS Reinstall |GTS,LC28,SDR4
Какая версия SQL Server? mssqltips.com/sqlservertip/2022/…