2010-10-03 4 views
5

J'ai 3 tables qui ressemblent à ceci:Aidez-moi écrire une requête SQL Crosstab

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 

et je voudrais écrire une requête qui renvoie une table qui ressemble à ceci:

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 

J'ai essayé de chercher des exemples, mais je n'ai pas vraiment trouvé quelque chose qui semble identique. Toute aide serait appréciée Merci.

Rechercher définitivement quelque chose qui permet de changer et d'ajouter/supprimer des catégories.

Répondre

3

Utilisation:

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 - Et s'il n'y a pas de limite au nombre de catégories? – LittleBobbyTables

+0

@LittleBobbyTables: Si c'est le cas, SQL dynamique. Mais l'OP n'a pas spécifié quelle base de données fournir des informations sur la syntaxe SQL dynamique à utiliser. –

+0

aurait dû spécifier, je veux avoir des catégories dynamiques –

0

Je voulais juste dire un peu plus sur ce que OMG Poneys m'a fourni:

@"    
      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    
     " 

les noms de table Je suis un peu différent de ce que j'ai commencé avec, mais les principaux changements sont que j'ai fait la JOIN dans une jointure à gauche pour inclure vid eos qui n'avait pas encore été marqué d'une catégorie. En outre, j'ai inclus une clause where.

Questions connexes