sql >> データベース >  >> RDS >> Sqlserver

動的列と同じ行での SQL 複数カウント

    SQL Server を使用しているため、PIVOT 関数を実装できます。ピリオド値の数が不明な場合は、動的 SQL を使用する必要があります:

    DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)select @cols =STUFF((SELECT distinct ',' + QUOTENAME('PeriodId'+cast(periodid as varchar(10))) ) from Periods FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')set @query ='SELECT resourcecode, ' + @cols + ' , Total from ( select s.resourcecode, ''PeriodId''+cast(p.periodid as varchar(10)) period, count(*) over(partition by s.resourcecode) 残りの期間 p からの合計 p のスケジュール s に参加します。 periodid =s.periodid ) x pivot ( count(period) for period in (' + @cols + ') ) p resourcecode が null でない場合 resourcecode'execute(@query) による順序 

    デモによる SQL Fiddle を参照してください。 .これにより結果が得られます:

    <プレ>|リソースコード | PERIODID1 | PERIODID2 | PERIODID3 | PERIODID4 | PERIODID5 | PERIODID6 | PERIODID7 | PERIODID8 |合計 |------------------------------------------------ -------------------------------------------------- ----------------------| AA | 2 | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 5 || BB | 2 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 4 || CC | CC | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 3 |

    MySQL でタグ付けされた以前の質問に基づいて、MySQL をデータベースとして使用していると想定しています。その場合、PIVOT 関数がないため、集計関数と CASE 式を使用して、データの行を列に変換する必要があります。

    列の値がわかっている場合は、クエリをハードコーディングできます:

    select resourcecode, sum(case when period ='PeriodId1' then 1 else 0 end) PeriodId1, sum(case when period ='PeriodId2' then 1 else 0 end) PeriodId2, sum(case when period =' PeriodId3' の場合は 1 でなければ 0 終了) PeriodId3, sum(期間 ='PeriodId4' の場合は 1 の場合、そうでない場合は 0 終了) PeriodId4, sum(期間 ='PeriodId5' の場合は 1 の場合、終了) PeriodId5, sum(期間 ='PeriodId4' の場合は 1 の場合、終了) 'PeriodId6' の場合 1 でなければ 0 終了) PeriodId6, sum(期間 ='PeriodId7' の場合 1 でなければ 0 終了) PeriodId7, 合計(期間 ='PeriodId8' の場合 1 でなければ 0 終了) PeriodId8, count(*) Totalfrom ( select concat('PeriodId', p.periodid) Period, s.resourcecode from period p left join schedule s on p.periodid =s.periodid) dwhere resourcecode is not nullgroup by resourcecode; 

    SQL Fiddle with Demo を参照してください。 .ただし、値が不明または動的である場合は、準備済みステートメントを使用して、実行する SQL 文字列を生成する必要があります。

    SET @sql =NULL;SELECT GROUP_CONCAT(DISTINCT CONCAT( 'sum(CASE WHEN period =''', concat('PeriodId', periodid), ''' THEN 1 else 0 END) AS `' , concat('PeriodId', periodid), '`' ) ) INTO @sqlFROM 期間;SET @sql =CONCAT('SELECT resourcecode, ', @sql, ' , count(*) Total from ( select concat(''PeriodId '', p.periodid) Period, s.resourcecode from period p left join schedule s on p.periodid =s.periodid ) d where resourcecode is not null group by resourcecode');PREPARE stmt FROM @sql;EXECUTE stmt;DEALLOCATE PREPARE stmt; 

    デモによる SQL Fiddle を参照してください。 .



    1. MySQL –ランダム番号を生成する方法

    2. 複数の列のMAXエントリのGREATESTが存在する行のMySQLSELECTID

    3. JPQLクエリのコレクションでNULLをチェックしていますか?

    4. SaaSサブスクリプションデータモデル