2010-10-03 11 views
5

mam 3 tabele, które wyglądają tak:Pomóż mi napisać zapytanie SQL krzyżowej

tblVideo: 
    VideoID  | Video Name 
      1    video 1 
      2    video 2 
      3    video 3 
      4    video 4 

tblCategory: 
    CategoryID | CategoryName 
      1   category1 
      2   category2 
      3   category3 

tblVideoCategory: 
    VideoID | CategoryID 
      1    3 
      2    1 
      2    2 
      3    1 
      3    2 
      3    3 
      4    1 

i chciałbym napisać zapytanie, które zwróci tabelę, która wygląda tak:

vVideoCategory: 
VideoID | VideoName | category1 | category2 | category3 
    1   video 1   false   false   true 
    2   video 2   true   true   false 
    3   video 3   true   true   true 
    4   video 4   true   false   false 

Próbowałem rozglądać się za przykładami, ale nie znalazłem niczego, co wydaje się takie samo. Każda pomoc będzie doceniona, dzięki.

Zdecydowanie poszukuję czegoś, co pozwoli na zmianę i dodanie/usunięcie kategorii.

Odpowiedz

3

Zastosowanie:

SELECT v.videoid, 
     v.video_name, 
     COALESCE(MAX(CASE WHEN vc.categoryid = 1 THEN 'true' END), 'false') AS category1, 
     COALESCE(MAX(CASE WHEN vc.categoryid = 2 THEN 'true' END), 'false') AS category2, 
     COALESCE(MAX(CASE WHEN vc.categoryid = 3 THEN 'true' END), 'false') AS category3 
    FROM tblvideo v 
    JOIN tblvideocategory vc ON vc.videoid = v.videoid 
GROUP BY v.videoid, v.video_name 

SQL Server 2005+:

DECLARE @SQL AS NVARCHAR(4000) 
DECLARE @categoryid AS INT 

DECLARE CUR CURSOR FAST_FORWARD FOR 
    SELECT c.categoryid 
    FROM tblcategory c 
ORDER BY c.categoryid 

SET @SQL = N'SELECT v.videoid, 
        v.video_name, ' 

OPEN CUR 
FETCH NEXT FROM CUR INTO @categoryid 
WHILE @@FETCH_STATUS = 0 
BEGIN 

    SET @SQL = @SQL + ' COALESCE(MAX(CASE WHEN vc.categoryid = '+ @categoryid +' THEN 'true' END), 'false') AS category'+ @categoryid +' ,' 

    FETCH NEXT FROM CUR INTO @categoryid 
END 

CLOSE CUR; 
DEALLOCATE CUR; 

--Get rid of trailing comma at the end 
SELECT @SQL = SUBSTRING(@SQL, 1, LEN(@SQL) -1) 

SET @SQL = @SQL + ' FROM tblvideo v 
        JOIN tblvideocategory vc ON vc.videoid = v.videoid 
       GROUP BY v.videoid, v.video_name 
       ORDER BY v.videoid, v.video_name ' 

BEGIN 

    EXEC sp_executesql @SQL 

END 
+0

@OMG - A co, jeśli nie ma limitu liczby kategorii? – LittleBobbyTables

+0

@LittleBobbyTables: Jeśli tak jest, dynamiczny SQL. Ale OP nie określił, która baza danych zawiera informacje o dynamicznej składni SQL, której należy użyć. –

+0

powinien mieć określone, chcę mieć dynamiczne kategorie –

0

prostu chciał poszerzyć trochę na tym, co OMG Ponies dostarczyła mi:

@"    
      DECLARE @SQL AS NVARCHAR(4000) 
      DECLARE @categoryid AS INT 

      DECLARE CUR CURSOR FAST_FORWARD FOR 
       SELECT c.categoryid 
       FROM Category c 
      ORDER BY c.categoryid 

      SET @SQL = 'SELECT v.videoid, v.title, v.Tags, ' 

      OPEN CUR 
      FETCH NEXT FROM CUR INTO @categoryid 
      WHILE @@FETCH_STATUS = 0 
      BEGIN 
       SET @SQL = @SQL + ' COALESCE(MAX(CASE WHEN vc.categoryid = ' + str(@categoryid) + ' THEN ''true'' END), ''false'') AS [category' + ltrim(str(@categoryid)) + '] ,' 
       FETCH NEXT FROM CUR INTO @categoryid 
      END 

      CLOSE CUR; 
      DEALLOCATE CUR; 

      --Get rid of trailing comma at the end 
      SELECT @SQL = SUBSTRING(@SQL, 1, LEN(@SQL) -1) 

      SET @SQL = @SQL + ' FROM Video v 
           LEFT JOIN VideoCategory vc ON vc.videoid = v.videoid 
          " + where+ @" 
          GROUP BY v.videoid, v.title, v.Tags 
          ORDER BY v.title, v.videoid, v.Tags ' 

      BEGIN 
       EXEC sp_executesql @SQL 
      END    
     " 

nazw tabel są nieco inne niż początkowo, ale główne zmiany polegają na tym, że JOIN ustawiłem w LEFT JOIN, aby dołączyć vid eos, które nie zostały jeszcze oznaczone kategorią. Dodałem także klauzulę where.

Powiązane problemy