Стратегия очистки данных из нескольких источников

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

Допустим, структура таблицы следующая (в реальной таблице гораздо больше столбцов):

create table dbo.infoBySource
(
    entityId     int
    ,dataSourceId int
    ,col1         varchar(50)
    ,col2         int
    ,constraint pk_infoBySource primary key (entityId, dataSourceId)
)

insert dbo.infoBySource values  
(1 ,1 ,'a' ,null),    
(1 ,2 ,'a2' ,10),    
(2 ,2 ,'c' ,20)

Я хотел бы написать запрос, который удаляет поле dataSourceId, сохраняя «лучшую» доступную информацию (столбец за столбцом), игнорируя null информацию. Здесь предполагается, что различные источники данных упорядочены по «приоритету качества» (предположим для простоты, что этот приоритет задается самим значением dataSourceId)

Это лучшее решение, к которому я пришел:

;with
    info   as
    (select
     a.*
    ,isCol1ToKeep =  case when ROW_NUMBER() over(partition by entityId 
                order by case when a.col1 is null then null else -dataSourceId end desc) = 1 then 1 else 0 end
    
    ,isCol2ToKeep =  case when ROW_NUMBER() over(partition by entityId 
                order by case when a.col2 is null then null else -dataSourceId end desc) = 1 then 1 else 0 end

        from
            dbo.infoBySource a
    )

select
    i.entityId
    ,col1 = max(case when i.isCol1ToKeep = 1 then i.col1 else null end)
    ,col2 = max(case when i.isCol2ToKeep = 1 then i.col2 else null end)

from
    info i

group by i.entityId

Но я думаю, что мое решение неудовлетворительно: его сложно поддерживать, оно подвержено ошибкам и, возможно, неэффективно. Есть ли лучшая стратегия?

Вероятно, вы можете упростить и использовать: FIRST_VALUE(colX) OVER(ORER BY case when colX IS NOT NULL THEN 0 ELSE 1 END, ...

siggemannen 11.07.2024 11:57
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы используете SQL Server 2022 или более позднюю версию, вы можете использовать оконную функцию FIRST_VALUE с опцией IGNORE NULLS:

WITH info AS (
  SELECT entityId,
     isCol1ToKeep = FIRST_VALUE(col1 ) IGNORE NULLS OVER(PARTITION BY entityId  ORDER BY dataSourceId),
     isCol2ToKeep = FIRST_VALUE(col2 ) IGNORE NULLS OVER(PARTITION BY entityId  ORDER BY dataSourceId)
  FROM dbo.infoBySource
)
SELECT entityId
      ,col1 = max(isCol1ToKeep)
      ,col2 = max(isCol2ToKeep)
FROM info
GROUP BY entityId

Я использую Azure SQL, он работает и намного чище, чем мое решение, спасибо.

AleV 11.07.2024 12:44

Рад слышать, что смог помочь :)

SelVazi 11.07.2024 13:23

Я успешно использую ваше решение, мне просто интересно, как сообщить моему редактору (Azure Data Studio 1.48.1), что этот синтаксис действительно действителен в SQL Azure: он продолжает добавлять красную волнистую линию под ключевым словом IGNORE, и я не могу найти, где указать целевой диалект SQL

AleV 17.07.2024 09:45

Другие вопросы по теме