Объединение таблиц на основе столбца без создания записей для каждой комбинации - PullRequest
0 голосов
/ 20 марта 2012

У меня есть две таблицы следующим образом:

Customer | Product
------------------
    A    |   Car
    A    |  Bike
    A    |  Boat
    B    |   Foo
    B    |   Bar

Customer | Friends
------------------
    A    |   John
    A    |  Andrew
    B    |   Baz

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

Customer   Products    Friends
------------------------------
A       - Car       - John
        - Bike      - Andrew
        - Boat
------------------------------
B       - Foo       - Baz
        - Bar     

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

Выходные списки с '-' не обязательно должны быть ячейками таблицы, они могут быть <ul> s.

Как этого добиться?Я хотел бы привязать к ASP.net GridView.Должен ли я попытаться сделать все это в одном запросе или использовать несколько запросов и каким-то образом добавить их в одну и ту же таблицу?


Каждая строка фактически является частью длинного отчета.По сути, каждая строка отчета содержит идентификатор клиента, кучу других полей, которые соответствуют один к одному с идентификатором клиента, а затем два списка для каждого идентификатора клиента, который я описал.Возможно, я могу использовать отдельный запрос для каждого списка, а затем вручную добавить каждый список в сетку на RowDataBound или аналогичный?

Ответы [ 3 ]

3 голосов
/ 20 марта 2012

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

;with OrderedProducts as (
    select Customer,Product,ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Product) rn
    from @Products
), OrderedFriends as (
    select Customer,Friend,ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Friend) rn
    from @Friends
)
select
    CASE WHEN COALESCE(op.rn,ofr.rn) = 1 THEN COALESCE(op.Customer,ofr.Customer) END,
    op.Product,
    ofr.Friend
from
    OrderedProducts op
        full outer join
    OrderedFriends ofr
        on
            op.Customer = ofr.Customer and
            op.rn = ofr.rn
order by COALESCE(op.Customer,ofr.Customer),COALESCE(op.rn,ofr.rn)

Дает результат:

     Product Friend
---- ------- ------
A    Bike    Andrew
NULL Boat    John
NULL Car     NULL
B    Bar     Baz
NULL Foo     NULL

По сути, так как у вас, кажется, нет ни одного, я разработал свое собственное правило для случаев, когда две строки совпадают между этими двумя таблицами, - чтобы строки были пронумерованы в алфавитном порядке для каждого клиента, а затем использовал эти номера строк для создания уникальные совпадения между таблицами.

* * * * * * * * * * * * * * * * * * * * * Для того, чтобы иметь дело с клиентами с друзьями, без продуктов, без продуктов, без друзей. CASE был единственным способом, которым я мог понять, чтобы имя клиента отображалось только в одном ряду.


И вот как я настроил пример данных:

declare @Products table (
    Customer char(1) not null,
    Product varchar(4) not null
)
insert into @Products (Customer , Product) values
(    'A'    ,   'Car'),
(    'A'    ,  'Bike'),
(    'A'    ,  'Boat'),
(    'B'    ,   'Foo'),
(    'B'    ,   'Bar')

declare @Friends table (
    Customer char(1) not null,
    Friend varchar(6) not null
)
insert into @Friends (Customer , Friend) values
(    'A'    ,   'John'),
(    'A'    ,  'Andrew'),
(    'B'    ,   'Baz')
1 голос
/ 20 марта 2012

Вам нужно 2 отдельных запроса, так как вы просто хотите получить список данных в 2 таблицах (с таким же условием где)

Какой движок SQL вы используете?

0 голосов
/ 20 марта 2012

(Это большой комментарий)

Набор результатов, который вы задали в вопросе, состоит из трех строк:

 Customer   Products    Friends
 ------------------------------
 A        - Car       - John
 <NULL>   - Bike      - Andrew
 <NULL>   - Boat      - <NULL>

Поскольку SQL не процедурный, а основанный на множестве, он функциональноэквивалентно

 Customer   Products    Friends
 ------------------------------
 <NULL>   - Boat      - <NULL>
 <NULL>   - Bike      - Andrew
 A        - Car       - John

, что не имеет смысла (еще меньше в примере с двумя людьми).

То, что вы в основном хотите, чтобы каждый человек получил список продуктов и списокавтомобилей, и отобразить это в одной сетке.

  • Но как определить, какой товар «соответствует» каждому другу, поскольку они будут в одном ряду?
  • Что происходит с пустыми значениями, если в сетке в середине списка друзей есть разрыв страницы?
  • Как сортировать строки по пустым значениям?

В этом случае, я думаю, вам будет лучше, если вы просто получите все данные из базы данных всервер, и выполните построение источника данных GridView с VB.NET.

...