Как сделать расширенные предикаты / подсказки SQL-соединения, чтобы избежать нежелательных строк? - PullRequest
0 голосов
/ 25 апреля 2019

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

У меня есть четыре стола.

  • В таблице 1 представлены отчеты о неисправных устройствах.
  • Таблица 2 - это таблица инвентаризации, полная деталей устройств и т. Д.
  • Таблица 3 представляет заказы на замену.
  • Таблица 4 представляет отношения заказов-замен.

Итак, записи такие.

table 1 are something like.
orderNo -  reported item 
1               1
1               2
2              56
2              34
2              23
3              15

table 2 
device id    lots of device detailed stuff in columns.
1              ...
2              ...
3              ...
...
15
23
34
56

table 3 (replacements)
rmaid   replacement
1           3
1           4
2           7
2           8
2           9
3           16

Это пример проблемы, которую я пытаюсь решить, и где возникает мой вопрос.

create table report(
    ID  int  not null,
    itemID int );

    insert into report (ID, ItemID)
    values (1,1),(1,2),(2,56),(2,34),(2,23),(3,15)

    create table device(
    ID int not null,
    dev_detail nvarchar(50) 
    );

    insert into device (ID, dev_detail)
    values (1,'det1'),(2,'det2'),(3,'det3'),(4,'det4'),(5,'det5'),
        (6,'det6'),(7,'det7'),(8,'det8'),(9,'det9'),(15,'det15'),
        (16,'det16'),(23,'dev23'),(34,'det34'),(56,'det56')

    create table replacement(
    id  int not null,
    ItemID int );

    insert into replacement (ID, ItemID)
    values (1,3),(1,4),(2,7),(2,8),(2,9),(3,16)

    create table [report-replacement](
    ID int not null,
    reportID int,
    replaceID int);

    insert into [report-replacement] (ID, reportID, replaceID)
    values (1,1,1),(2,2,2),(3,3,3)

    select 
    rep.ID as report_id,
    rep.itemID as reported_item,
    rep.dev_detail as reported_item_detail,
    rep.replaceID as report_replace_id,
    rma.id as rma_id,
    rma.ItemID as rma_item,
    rma.dev_detail as rma_item_detail

    from
    (
      select report.ID,report.itemID,device.dev_detail, replaceID
      from 
       report 
        inner join device on report.itemID = device.ID
        inner join [report-replacement] on reportID = [report-replacement].reportID
    ) as Rep
    inner join
    (
      select 
      replacement.id,replacement.ItemID,device.dev_detail
      from 
      replacement 
      inner join device on replacement.ItemID = device.ID
    ) as RMA
    on Rep.replaceID = RMA.id

    drop table report, device,replacement,[report-replacement]

Это желаемый вывод, я хотел бы помочь в построении предикатного соединения для основного внутреннего соединения, чтобы я получал соотношение 1: 1 зарегистрированных элементов к замененным элементам:

report id, item id, item details, rma_id, rma_item, rma_item_detail
1           1           det1        1        3          det3
1           2           det2        1        4          det4
2           56          det56       2        7          det7
2           34          det34       2        8          det8
2           23          det23       2        9          det9
3           15          det15       3       16          det16

Это результат выполнения примера кода, проблема в том, что я получаю много строк, и я использую только внутренние соединения. Их не должно быть много, и мой вопрос в том, есть ли предикат pecial join, какой-нибудь умный способ получить желаемый результат.

report_id   reported_item   reported_item_detail    report_replace_id   rma_id  rma_item    rma_item_detail
    1           1               det1                    1               1       3           det3
    1           2               det2                    1               1       3           det3
    2           56              det56                   1               1       3           det3
    2           34              det34                   1               1       3           det3
    2           23              dev23                   1               1       3           det3
    3           15              det15                   1               1       3           det3
    1           1               det1                    1               1       4           det4
    1           2               det2                    1               1       4           det4
    2           56              det56                   1               1       4           det4
    2           34              det34                   1               1       4           det4
    2           23              dev23                   1               1       4           det4
    3           15              det15                   1               1       4           det4
    1           1               det1                    2               2       7           det7
    1           2               det2                    2               2       7           det7
    2           56              det56                   2               2       7           det7
    2           34              det34                   2               2       7           det7
    2           23              dev23                   2               2       7           det7
    3           15              det15                   2               2       7           det7
    1           1               det1                    2               2       8           det8
    1           2               det2                    2               2       8           det8
    2           56              det56                   2               2       8           det8
    2           34              det34                   2               2       8           det8
    2           23              dev23                   2               2       8           det8
    3           15              det15                   2               2       8           det8
    1           1               det1                    2               2       9           det9
    1           2               det2                    2               2       9           det9
    2           56              det56                   2               2       9           det9
    2           34              det34                   2               2       9           det9
    2           23              dev23                   2               2       9           det9
    3           15              det15                   2               2       9           det9
    1           1               det1                    3               3       16          det16
    1           2               det2                    3               3       16          det16
    2           56              det56                   3               3       16          det16
    2           34              det34                   3               3       16          det16
    2           23              dev23                   3               3       16          det16
    3           15              det15                   3               3       16          det16

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

Я обнаружил, что оба соединения RMA и Reps в порядке при соединении с таблицей сведений об устройстве, но внутреннее объединение отчетов таблицы с таблицей [report-replace] не работает должным образом, поэтому я изменил порядок предложений on из reportID = [отчет-замена] .reportID для [report-replace] .reportID = reportID, и это уменьшило количество строк с 36 до 14 строк.

1 Ответ

2 голосов
/ 05 мая 2019

Это решение моего вопроса.

select 
rep.ID as report_id,
rep.itemID as reported_item,
rep.dev_detail as reported_item_detail,
rep.replaceID as report_replace_id,
rma.id as rma_id,
rma.ItemID as rma_item,
rma.dev_detail as rma_item_detail,
Rep.seq,
rma.seq
from
(
  select report.ID,report.itemID,device.dev_detail, [report-replacement].replaceID,
  ROW_NUMBER() OVER (PARTITION BY report.id ORDER BY report.id) AS seq
  from 
   report 
    inner join device on device.ID = Report.ID
    inner join [report-replacement] on [report-replacement].reportID = Report.ID
) as Rep
inner join
(
  select
  replacement.id,replacement.ItemID,device.dev_detail,
  ROW_NUMBER() OVER (PARTITION BY replacement.id ORDER BY replacement.id) AS seq
  from 
  replacement 
  inner join device on device.ID = replacement.ItemID
) as RMA
on rep.replaceID = RMA.id AND rep.seq=rma.seq

Проблема обычно называется перекрестным соединением через прокси.

Решение, похоже, основано на использовании ROW_NUMBER () OVER(PARTITION BY replace.id ORDER BY replace.id) AS seq

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