Соединительные таблицы SQL - PullRequest
6 голосов
/ 12 марта 2010

Таблица 1 содержит

ID|Name  
1  Mary  
2  John  

Таблица 2 содержит

ID|Color  
1  Red  
2  Blue  
2  Green  
2  Black  

Я хочу закончить с

ID|Name|Red|Blue|Green|Black  
1  Mary Y   Y  
2  John     Y     Y     Y

Спасибо за любую помощь.


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

Ответы [ 5 ]

6 голосов
/ 12 марта 2010

Если вы используете T-SQL, вы можете использовать PIVOT (http://msdn.microsoft.com/en-us/library/ms177410.aspx)

Вот запрос, который я использовал:

declare @tbl_names table(id int, name varchar(100))
declare @tbl_colors table(id int, color varchar(100))

insert into @tbl_names
select 1, 'Mary'
union
select 2, 'John'


insert into @tbl_colors
select 1, 'Red'
union
select 1, 'Blue'
union
select 2, 'Green'
union
select 2, 'Blue'
union
select 2, 'Black'

select name,
        case when [Red] is not null then 'Y' else '' end as Red,
        case when [Blue] is not null then 'Y' else '' end as Blue,
        case when [Green] is not null then 'Y' else '' end as Green,
        case when [Black] is not null then 'Y' else '' end as Black

from
(
select n.id, name, color from @tbl_names n
inner join @tbl_colors c on n.id = c.id
) as subq
pivot 
(
    min(id)
    FOR color IN ([Red], [Blue], [Green], [Black])
) as pvt

А вот и вывод:

John        Y   Y   Y
Mary    Y   Y       
2 голосов
/ 12 марта 2010

Я могу использовать оператор CASE с подзапросом для ввода значений Y.

select ID, Name,
  case
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Red') then
      'Y'
    else
      NULL
  end
,
 case
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Blue') then
      'Y'
    else
      NULL
  end
,
 case
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Green') then
      'Y'
    else
      NULL
  end
,
 case
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Black') then
      'Y'
    else
      NULL
  end
from Names N
1 голос
/ 12 марта 2010

Как отмечали другие комментаторы, вы не показываете, как именно вы связываете людей и цвета. Если вы используете таблицу ссылок (person_id, color_id), то нет способа решить эту проблему в стандартном SQL, поскольку для этого требуется сводная таблица или перекрестная табуляция, которая не является частью стандартного SQL.

Если вы хотите добавить условие, что количество цветов ограничено и известно, и время разработки, вы можете предложить решение, использующее одно соединение для каждого цвета и функции CASE или IF в SQL. Но это было бы не элегантно, и, кроме того, я бы не поверил, что это условие будет оставаться верным очень долго.

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

В противном случае вам придется сделать это с помощью хранимой процедуры или кода приложения.

1 голос
/ 12 марта 2010

Я думаю, вам придётся что-то вроде этого:

SELECT  t1.ID, 
        t1.Name, 
        CASE 
            WHEN red.ID IS NULL THEN '' 
            ELSE 'Y' 
        END As Red,
        CASE 
            WHEN blue.ID IS NULL THEN '' 
            ELSE 'Y' 
        END As Blue
FROM    Table1 t1 
    LEFT JOIN   Table2 Red 
        ON t1.ID = Red.ID AND Red.Color = 'Red'
    LEFT JOIN   Table2 Blue
        ON t1.ID = Blue.ID AND Blue.Color = 'Blue'

MS Sql не поддерживает запросы PIVOT, такие как MS Access.

0 голосов
/ 12 марта 2010

Вопреки тому, что сказали другие плакаты; Я не вижу необходимости в третьем столе. Если цвета являются хорошо известным перечислением в вашем приложении, то вам не нужна таблица «Цвет».

Что вы ищете, так это PIVOT one .

...