Проблема SQL-запроса - PullRequest
2 голосов
/ 05 апреля 2011

Допустим, у меня есть два стола: «Сад» и «Цветы».Между этими таблицами существует отношение 1: n, потому что в саду может быть много цветов.Можно ли написать запрос SQL, который возвращает результат со следующей структурой:

GardenName     Flower1Name      Flower2Name .... (as long as there are entries in flowers)
myGarden        rose             tulip

Ответы [ 4 ]

8 голосов
/ 05 апреля 2011
CREATE TABLE #Garden (Id INT, Name VARCHAR(20))
INSERT INTO #Garden
SELECT 1, 'myGarden' UNION ALL
SELECT 2, 'yourGarden'

CREATE TABLE #Flowers (GardenId INT, Flower VARCHAR(20))
INSERT INTO #Flowers
SELECT  1, 'rose'  UNION ALL
SELECT  1, 'tulip'  UNION ALL
SELECT  2, 'thistle' 

DECLARE @ColList nvarchar(max)

SELECT @ColList = ISNULL(@ColList + ',','') + QUOTENAME('Flower' + CAST(ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS VARCHAR))
FROM #Flowers WHERE GardenId = (
SELECT TOP 1 GardenId
FROM #Flowers
ORDER BY COUNT(*) OVER (PARTITION BY GardenId) DESC

)

EXEC (N'
;WITH cte As
(
SELECT *, ''Flower'' + CAST(ROW_NUMBER() OVER (PARTITION BY GardenId ORDER BY (SELECT 0)) AS VARCHAR) RN
FROM #Flowers F
)
SELECT Name,' + @ColList + N'
FROM cte 
JOIN #Garden g ON g.Id = GardenId
PIVOT (MAX(Flower) FOR RN IN (' + @ColList + N')) Pvt')


DROP TABLE #Garden
DROP TABLE #Flowers

Возвращает

Name                 Flower1              Flower2
-------------------- -------------------- --------------------
myGarden             rose                 tulip
yourGarden           thistle              NULL
6 голосов
/ 05 апреля 2011

Посмотрите на использование Pivot в SQL Server. Вот хорошая ссылка, которая рассказывает, как это работает:

http://www.kodyaz.com/articles/t-sql-pivot-tables-in-sql-server-tutorial-with-examples.aspx

Хорошо, я думаю, у меня все получилось. Попробуйте это:

with temp as
(
    select 'myGarden' as name, 'test1' as flower
    union
    select 'myGarden','test2'
    union
    select 'myGarden','test5'
    union
    select 'abeGarden','test4'
    union
    select 'abeGarden','test5'
    union 
    select 'martinGarden', 'test2'
)

select* from temp
pivot
(
  max(flower)
  for flower in (test1,test2,test3,test4,test5)
) PivotTable

Вы также можете сделать значения в предложении in динамическими. Так как это CTE, я не могу в моем примере.

2 голосов
/ 05 апреля 2011

Динамический SQL с курсором - единственный способ, о котором я могу думать, и он не будет красивым.

0 голосов
/ 05 апреля 2011

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

select gardenName from tblGarden where gardenid = 1 
Union ALL 
select tblFLowers.flowerName from tblFlowers where gardenid = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...