Для каждой строки в таблице, получить любую связанную строку в другой таблице - PullRequest
1 голос
/ 30 июля 2010

С учетом следующих (сильно упрощенных) таблиц:

create table Tags (
   TagId int Primary Key
)

create table OrderLines (
   Branch int,
   Station int,
   TransNo int,
   TagId int foreign key references Tags,
   primary key (Branch, Station, TransNo)
)

Мне нужен список тегов вместе с OrderLine, который ссылается на каждый тег. Я ожидаю, что ноль или один OrderLines будут ссылаться на каждый тег, но в ограничениях базы данных нет ничего для обеспечения этого.

С учетом ввода, как это:

 OrderLines                                     Tags
 Branch Station TransNo TagId                   TagId
 1      100     2345    1                       1
 1      100     2346    1                       2
 1      101     5223    2                       3
 3      100     6677    4                       4

Я хочу получить вывод, подобный этому:

  TagId     Branch    Station    TransNo  
  1         1         100        2345     <-- it could list 2346 here, don't care
  2         1         101        5223     
  3         null      null       null
  4         3         100        6677

Обратите внимание, что хотя на TagId 1 ссылаются дважды, мой вывод содержит только один из них. Неважно, какой OrderLine указан рядом с ним, но в выводе должен быть только один экземпляр каждого тега.

Какой самый эффективный способ сделать это?

Я не могу изменить схему базы данных.

Ответы [ 4 ]

2 голосов
/ 30 июля 2010
select t.TagId, t.Station, t.Branch, t.TransNo
from (
SELECT Station, Branch, TransNo, TagId, ROW_NUMBER() OVER (partition by TagId order by TagId) r
From OrderLines) t
WHERE r = 1
UNION ALL
SELECT TagId, NULL, NULL, NULL
from Tags
WHERE NOT EXISTS (Select 1 from OrderLines ol Where ol.TagId = Tags.Id)
2 голосов
/ 30 июля 2010

Вы должны посмотреть на план выполнения, чтобы оценить эффективность

;WITH O AS
(
SELECT Branch, Station, TransNo, TagId,
ROW_NUMBER() OVER (PARTITION BY TagId ORDER BY TagId ) AS RN
FROM OrderLines
)
    SELECT T.TagID, O.Branch, O.Station, O.TransNo
        FROM Tags T
        LEFT JOIN O ON T.TagID = O.TagID and RN=1
0 голосов
/ 30 июля 2010
   select
        T.tagid,
        O.branch,
        O.station,
        O.transno
    from orderlines O
    right join tags T on (t.tagid=O.tagid)
    group by t.tagid

Результат:

  tagid branch  station transno
1   1   100 2345
2   1   101 5223
3   NULL    NULL    NULL
4   3   100 6677
0 голосов
/ 30 июля 2010
SELECT Tags.TagID, Branch, Station, TransNo
    FROM Tags
    LEFT JOIN OrderLines ON Tags.TagID = OrderLines.TagID
    ORDER BY Tags.TagID

При левом соединении будут перечислены все теги, даже те, к которым не прикреплена строка заказа.Единственный недостаток заключается в том, что если более одной строки заказа ссылается на тег, тег будет указан один раз для каждой строки заказа.Некоторые СУБД (например, MySQL) позволяют вам решить эту проблему с помощью GROUP BY и по-прежнему выбирать столбцы, по которым вы не группируете, но это нестандартно и нет никакой гарантии, какую OrderLine вы получите.Если вы хотите этого, вам придется прибегнуть к подзапросам, объединениям, временным таблицам или представлениям (но поскольку вы не можете изменить схему, последний вариант отсутствует).

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