Назначьте название продукта на основе условий, указанных в SQL Server. - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь написать SQL-запрос на основе следующих условий:

ПРОДУКТ

Product Table

ЗАКАЗА

enter image description here

Таблица продукта содержит 3 столбца на основе следующего запроса: CREATE Product (МастерПродукт nvarchar (50), Productkey int, ProductName nvarchar (50))

Таблица заказов состоит из 3 столбцов на основе следующего запроса: CREATE Order (MasterProduct nvarchar (50), Orderno int, Productkey int, ParentProduct int)

Сценарий:

Столбец «MasterProduct» в таблице «Товар» должен быть присвоен конкретному заказу в таблице заказов на основе следующих условий:

1) Если все ключи продуктов в таблице продуктов для конкретного основного продукта соответствуют номеру заказа в таблице заказов

И

Первый ProductKey является родителем для его непосредственного ключа продукта в таблице заказов

Пример : Номер заказа 'S1' назначается Kebab в качестве основного продукта для таблицы заказов, поскольку ключи продукта 1 и 2 из таблицы продуктов оба существуют в S1, а также ключ продукта 1 является родительским ключом продукта к ключам продукта 2 и 4.

С другой стороны, к номеру заказа 'S2' не назначен какой-либо основной продукт (NULL), поскольку он имеет только '1' в качестве ключа продукта и отсутствует '2', в противном случае ему будет присвоен Kebab.

S3 также назначен Метро, ​​потому что у него есть ключи продукта 30 и 31 из таблицы продуктов, присутствующие для этого номера заказа, а ключ продукта 30, который является родительским продуктом, назначен по крайней мере одному дочернему продукту, который называется '31'.

S4 не назначен главный продукт, хотя он имеет все ключи продукта для Subway (30,31), поскольку 30, который является родительским продуктом, не назначен ни одному дочернему продукту.

1 Ответ

0 голосов
/ 30 августа 2018

Это немного запутанно, но вот рабочая версия:

declare @p table(MasterProduct nvarchar(50), Productkey int, ProductName nvarchar(50))
declare @o table(OrderLineNumberKey int, Orderno int, Productkey int, ParentProduct int)
insert @p values('kebab',1,'chicken'),('kebab',2,'mayo'),('subway',30,'bread'),('subway',31,'salad')
insert @o values(1,1,1,null),(2,1,2,1),(3,1,4,1),(4,1,7,null)
insert @o values(1,2,1,null),(2,2,9,null),(3,2,14,1)
insert @o values(1,3,30,null),(2,3,31,30),(3,3,35,null)
insert @o values(1,4,30,null),(2,4,31,null),(3,4,39,null)

;with ParentChild as (
    select o.orderno, o.ProductKey as TopProductKey, o.productkey, p.masterproduct
    from @o o
    join @p p on p.productKey=o.ProductKey
    where parentproduct is null
    union all
    select pc.orderno,pc.ProductKey as TopProductKey,o.productkey,p.masterproduct
    from @o o
    join @p p on p.productKey=o.ProductKey
    join ParentChild pc on pc.orderno=o.orderno and pc.ProductKey=o.ParentProduct
    )

select case when HaveAll=1 then ordercheck.masterproduct end as masterproduct,
    o.orderno, o.productkey,o.parentproduct
from @o o
left join(
    select orderno, masterproduct, max(HaveAll) as HaveAll from (
        select pc1.orderno, p.masterproduct, min(case when pc2.productkey is null then 0 else 1 end) as HaveAll
        from ParentChild pc1
        join @p p on p.masterproduct=pc1.masterproduct
        left join ParentChild pc2 on pc2.orderno=pc1.orderno and pc2.MasterProduct=p.MasterProduct and pc2.productkey=p.productkey and pc2.topproductkey=pc1.topproductkey
        where pc1.TopProductKey=pc1.ProductKey
        group by pc1.orderno, p.masterproduct, pc1.TopProductKey
        ) q
        group by orderno, masterproduct
    ) ordercheck on ordercheck.orderno=o.orderno

Чтобы объяснить это, во-первых, в CTE мы рекурсивно просматриваем приказы, ищем всех возможных родителей с нулевым родителем и находим все их дочерние строки. Вы увидите, что у заказа 4 есть 2 возможных кандидата, которые усложняют ситуацию.

Затем в основном запросе есть внутренний подзапрос, который сравнивает все родительские + дочерние строки с моделью продукта и проверяет, что у нас есть все продукты. Он должен сделать это для каждого из родителей-кандидатов, а затем свернуть это во второй раз для общего заказа. Это должно быть сделано в случае, если было два кандидата в родители, один из которых был удовлетворен, а другой - нет.

Наконец, мы присоединяем это к заказам на возврат основного продукта, если у нас были все продукты, или к нулю, если у нас его нет.

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