T-SQL - получить настроенную строку, когда она существует - PullRequest
0 голосов
/ 21 июня 2019

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

У меня есть пример кода и мое решение, использующее ROW_NUMBER () для выбора строк. Похоже, этот ROW_NUMBER удлиняет наш запрос, поэтому я спрашиваю, видят ли кто-нибудь лучшие варианты для достижения тех же результатов.

Спасибо!

IF OBJECT_ID('tempdb..#TItems') IS NOT NULL
DROP TABLE #TItems
IF OBJECT_ID('tempdb..#TAttrib') IS NOT NULL
DROP TABLE #TAttrib

CREATE TABLE #TItems (ItemID int, Name varchar(50))
CREATE TABLE #TAttrib (AttribID  int, ClinicID int , ItemID int, AutoReorder bit, isFavorite bit, IsControlled bit )

Insert into #TItems (ItemId, Name) 
Select 1 as ItemID, 'Item1' as Name UNION
Select 2 as ItemID, 'Item2' as Name UNION
Select 3 as ItemID, 'Item3' as Name ;

INSERT INTO #TAttrib (AttribID , ClinicID, ItemID, AutoReorder , isFavorite , IsControlled  )
SELECT 10, NULL, 1,1,1,1 UNION
SELECT 20, NULL, 2,1,1,1 UNION
SELECT 30, NULL, 3,1,1,1 UNION
SELECT 40, 200, 1, 0,0,1 UNION
SELECT 50, 500, 2,1,0,0  UNION
SELECT 60, 500, 3,1,1,0  ;


-- Clinics 100, 300, 400 do not have Attrib.  They will use the vanilla attrib rows for items 1-3.
-- Clinic 200 has customized item 1, clinic 500 has customized item 3.
-- expected Attrib result set for clinic 100: AttribIDs 10, 20, 30
-- expected Attrib result set for clinic 200: AttribIDs  40, 20, 30
-- expected Attrib result set for clinic 500: AttribIDs  10, 50, 60

Declare @ClinicID int = 500
SELECT * FROM
(
SELECT AttribID, ClinicID , ItemID, ROW_NUMBER() OVER (
        PARTITION BY ItemID ORDER BY ClinicID DESC
        ) RN FROM #TAttrib
where ClinicID is NULL or ClinicID = @ClinicID ) RS
WHERE RN = 1

Ответы [ 2 ]

0 голосов
/ 21 июня 2019

Попробуйте использовать коррелированный подзапрос и union all:

select a.*
from #TAttrib a
where a.ClinicId = (select max(a2.ClinicId)
                    from #TAttrib a2
                    where a2.ItemID = a.ItemId
                   )
union all
select a.*
from #TAttrib a
where not exists (select 1
                  from #TAttrib a2
                  where a2.ItemID = a.ItemId and
                        a2.ClinicId is not null
                 );

Первый получает clinicid при наличии значения, отличного от NULL.Второй получает остальное.

Теперь, очень важно, вы хотите индекс на #TAttrib(ItemID, ClinicID) в состоянии для этих запросов:

create index idx_tattrib_itemid_clinicid on #TAttrib(ItemID, ClinicID);

Это также принесет пользу вашему запросу.

0 голосов
/ 21 июня 2019

Вы можете попробовать переместить функциональность row_number в join

select t.AttribId, t.ClinicID, t.ItemID
from #TAttrib t
  join (
    select ItemId,max(ClinicID) as ClinicID
    from #TAttrib
    where ClinicID is NULL or ClinicID = @ClinicID
    group by ItemId
    ) tm
    on t.ItemId=tm.ItemId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...