SQL View: объединять таблицы, не вызывая дублирования данных в каждой строке? - PullRequest
3 голосов
/ 18 февраля 2011

Всякий раз, когда я создаю представление из 3 таблиц, оно дублирует все данные во всех строках. Я не выясняю, как объединить их, чтобы они показывали нули вместо дубликатов. Можете ли вы указать мне в правильном направлении?

Вот сценарий:

  • Таблица 1 = Учетные записи: имена учетных записей и идентификаторы учетных записей
  • Таблица 2 = Свойства: описание свойства, адрес свойства и идентификаторы учетной записи
  • Таблица 3 = Транспортные средства: марка транспортного средства, модель транспортного средства и идентификаторы счета

Данные выглядят примерно так:

[Table 1= Accounts]
   id name  accountid

   1 Family A  account001
   2 Family B  account002
   3 Family C  account003



[Table 2= Properties]
  id accountid  description address

  1 account001 home california
  2 account001  beach mexico
  3 account002  hideout arizona
  4 account002  getaway nevada
  5 account002  skilodge idaho
  6 account 003  home texas


[Table 3= Vehicles]

 id description make model accountid
  1 green  Acura Integra  account001
  2 blue  Aston Martin Vantage account001
  3 silver  Audi Quattro  account001
  4 work  Bently Continental GTC account002
  5 kids  Ford Fusion Hybrid account002
  6 Mom's Car  Land Rover LR4 account003
  7 Paper Weight Mini Clubman account003
  8 Beater  Dodge Caliber  account003
  9 Why Mahindra TR40 account003
  10 Kids  Scion xB  account003

Мое желание - создать представление, которое показывает мне все записи в БД. Для каждой строки я хотел бы показать имя учетной записи, а затем данные из таблиц.

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

account_Name | property_DESCRIPTION | property_ADDRESS | vehicles_DESCRIPTION   vehicles_MAKE | vehicles_MODEL

- Family A  home    california  **null  null    null**
- Family A  beach   mexico  **null  null    null**
- Family A  **null  null**  blue    Aston Martin    Vantage
- Family A  **null  null**  silver  Audi    Quattro
- Family B  hideout arizona **null  null    null**
- Family B  getaway nevada  **null  null    null**
- Family B  skilodge    idaho   **null  null    null**
- Family B  **null  null**  kids    Ford    Fusion Hybrid

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

account_Name    property_DESCRIPTION    property_ADDRESS    vehicles_DESCRIPTION    vehicles_MAKE   vehicles_MODEL

- Family A  home    california  green   Acura   Integra
- Family A  beach   mexico  green   Acura   Integra
- Family A  home    california  blue    Aston Martin    Vantage
- Family A  beach   mexico  blue    Aston Martin    Vantage
- Family A  home    california  silver  Audi    Quattro
- Family A  beach   mexico  silver  Audi    Quattro
- Family B  hideout arizona work    Bently  Continental GTC
- Family B  getaway nevada  work    Bently  Continental GTC
- Family B  skilodge    idaho   work    Bently  Continental GTC
- Family B  hideout arizona kids    Ford    Fusion Hybrid
- Family B  getaway nevada  kids    Ford    Fusion Hybrid
- Family B  skilodge    idaho   kids    Ford    Fusion Hybrid

Почему это происходит, мне кажется, имеет смысл; это все в соединениях. Как будто объединения чувствуют, что им действительно нужно отображать данные независимо от их стоимости. Думая с точки зрения сценариев, мне кажется, что вместо объединений мне нужно по отдельности пройти по таблице, а затем объединить полученные циклы.

По сути, мне нужно, чтобы представление сначала показывало все записи из таблицы 1, затем все записи из таблицы 2, затем все записи из таблицы 3. На самом деле я не хочу объединять эти данные; Я просто хочу увидеть все это в одном представлении.

Может кто-нибудь подсказать мне, как создать желаемый вид выше, который показывает нули вместо дубликатов?

Это на SQL 2008 R2 Enterprise.

Ответы [ 2 ]

6 голосов
/ 18 февраля 2011

В этом случае вам необходимо использовать UNION (фактически UNION ALL).

select a.name as account_Name, 
       p.description as property_DESCRIPTION, 
       p.address as property_ADDRESS, 
       null as vehicles_DESCRIPTION,
       null as vehicles_MAKE, 
       null as vehicles_MODEL
    from Accounts a
        inner join Properties p
            on a.accountid = p.accountid
UNION ALL   
select a.name as account_Name, 
       null as property_DESCRIPTION, 
       null as property_ADDRESS, 
       v.description as vehicles_DESCRIPTION,
       v.make as vehicles_MAKE, 
       v.model as vehicles_MODEL
    from Accounts a
        inner join vehicles v
            on a.accountid = v.accountid
0 голосов
/ 18 февраля 2011

Где он просто не отображает данные в строке, если эти данные не попадают в столбец, к которому они обращались в данный момент.

Это не имеет смысла для меня (в том смысле, что я не понимаю смысла, не то, что это бессмысленно).

Причина, по которой вы видите данные, которые вы видите во втором, заключается в том, что нет никакой связи между транспортным средством и имуществом . Что у вас есть это:

Vehicles *-----| Account | -----* Properties

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

select
    *

from account a

join property p on p.accountid = a.accountid
join vehicle v on v.accountid = a.accountid

Ваш вид будет содержать строку для каждой комбинации транспортного средства и имущества в рамках данного аккаунта (который выглядит так, как будто вы видите).

Если вам нужен список учетных записей со списком свойств и списком транспортных средств (без связи между ними), то вам нужно создать два отдельных запроса и объединить их с union.

select
    a.accountid,
    p.property_name,
    null as vehicle_name

from account a

join property p on p.accountid = a.accountid

union

select
    a.accountid,
    null as property_name,
    v.vehicle_name

from account a

join property p on p.accountid = a.accountid
join vehicle v on v.accountid = a.accountid
...