2010-03-12 2 views
6

Таблица содержит одинSQL Регистрация Таблицы

ID|Name 
1 Mary 
2 John 

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

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 

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


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

+0

Какая база данных? –

+0

-1: Вы должны сообщить нам, какую СУБД вы используете. –

+0

Я использую ADO для подключения к Visual FoxPro DB. – Harley

ответ

6

Если вы используете 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  
+0

Три проблемы с этим решением: 1) данные, которые вы вставляете в таблицы, - это не данные, указанные в вопросе, 2) для этого требуется строго ограничивать список цветов во время разработки, что маловероятно, и 3) это SQL Server, а не решение VFP (хотя я думаю, что OP только добавил теги Foxpro после публикации решения). –

+0

Я взял данные из вопроса, похоже, что Харли редактировал его. То же самое касается Foxpro ... –

1

Я думаю, что вы» вам нужно будет что-то вроде этого:

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

Просто нужно исправить условия соединения на «и Red.Color» и «and Blue.Color». – DyingCactus

+0

SQl Server 2005 и выше действительно имеют PIVOT и UNPIVOT. – DancesWithBamboo

+0

Исправить это, но вы по-прежнему в конечном итоге строго набираете каждый столбец/переменную, на которую хотите повернуть. MS Access имеет возможность динамически создавать сводный запрос на основе значений. Вот что я имел в виду, говоря «как MS Access» – Ender

-1

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

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

2

Я могу использовать оператор 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 
+0

Я думаю, что это решение будет очень медленным ... так много подзапросов. – Ender

+0

@Ender Использование уникальных ограничений в таблице цветов может помочь улучшить план выполнения, поскольку он сможет предсказать, что подзапрос является скалярным запросом. Либо это, либо стержень, либо другой случай, который использует Ларри, для чего потребуется 4 соединения (или соединение для каждого возможного цвета). Когда вы вращаете данные наподобие этого, вы часто получаете некоторые довольно медленные запросы. Этого можно избежать с помощью лучшего дизайна таблицы, но похоже, что плакат ограничен тем, что уже реализовала сторонняя система. Я чувствую, что его боль вызывает тяжелую ситуацию. – AaronLS

1

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

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

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

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

+0

Нет ссылки, просто общий идентификатор. В таблице 2 в настоящее время у нас есть 11 возможных значений для «color», поэтому каждый уникальный идентификатор из таблицы может иметь до 11 записей в таблице 2. – Harley

+0

Кроме того, в таблице 1 содержится 285 000 записей, а в таблице 2 - 773 000, поэтому создание таблицы ссылок перед запуском запроса может быть непрактичным. Поскольку таблицы поддерживаются через стороннее программное обеспечение, чтобы их добавить, таблица ссылок на их код, вероятно, никогда не произойдет. – Harley

+0

Теперь становится более понятным, что вы обновили значения ID в таблице 2 от 1, 2, 3, 4 до 1, 2, 2, 2. Однако результат по-прежнему не соответствует вашим табличным данным, поскольку нет параметров Mary/Синяя запись в таблице 2. –