2010-10-03 21 views
5

Ho 3 tabelle che assomigliano a questo:aiutarmi a scrivere una query SQL a campi incrociati

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 

e vorrei scrivere una query che restituirà una tabella che assomiglia a questo:

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 

Ho provato a cercare degli esempi ma non ho ancora trovato nulla che sembra lo stesso. Qualsiasi aiuto sarebbe apprezzato, grazie.

Sicuramente alla ricerca di qualcosa che consenta di modificare e aggiungere/eliminare categorie.

risposta

3

Usa:

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 - Cosa succede se non c'è un limite al numero di categorie? – LittleBobbyTables

+0

@LittleBobbyTables: se questo è il caso, SQL dinamico. Ma l'OP non ha specificato quale database fornire informazioni sulla cui sintassi SQL dinamica usare. –

+0

dovrebbe aver specificato, voglio avere categorie dinamiche –

0

voleva solo espandere un po 'su ciò che OMG Ponies mi dotato di:

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

i nomi delle tabelle sono un po 'diversi da quelli con cui ho iniziato, ma i cambiamenti principali sono che ho fatto il JOIN in un JOIN SINISTRO per includere il video eos che non era ancora stato contrassegnato con una categoria. Inoltre, ho incluso una clausola where.

Problemi correlati