1

これは非常に簡単なはずですが、答えを見つけることができません (これは、14 時間近く SQL コーディングをしているせいだと思います)。

「Label」フィールドと「ReportYear」フィールドを持つ report というテーブルがあります。「Label」の値には 3 つの可能性があることはわかっていますが、すべてのラベルに毎年のエントリがあるわけではありません。

個別のラベル リストを選択すると、次のようになります。

'Regular'
'Special'
'None'

ここで手動でデータを選択すると、2011 年と 2010 年には「Special」というラベルのエントリがないことがわかりますが、この情報をまとめるにはクエリが必要です。

'Regular' - '2012' - '5'
'Regular' - '2011' - '2'
'Regular' - '2010' - '1'
'Special' - '2012' - '3'
'Special' - '2011' - '0'
'Special' - '2010' - '0'
'None' - '2012' - '10'
'None' - '2011' - '5'
'None' - '2010' - '2'

うまくいけば、それは理にかなっています。

私はできることを知っていますSELECT Count(*), Label FROM (SELECT DISTINCT Label FROM Report) t1...しかし、それでは?LEFT JOIN Report t2 ON t1.Label=t2.Label? CROSS JOIN?

私の脳は揚げられています。

ヘルプ?

4

1 に答える 1

1
SELECT
   L.Label,
   Y.ReportYear,
   ReportCount = Count(R.Label)
FROM
   (SELECT DISTINCT Label FROM dbo.Report) L
   CROSS JOIN (SELECT DISTINCT ReportYear FROM dbo.Report) Y
   LEFT JOIN dbo.Report R
      ON L.Label = R.Label
      AND Y.ReportYear = R.ReportYear
GROUP BY
   L.Label,
   Y.ReportYear

ラベルと年を取得するためだけにテーブル全体を 2 回スキャンしているため、これはあまり理想的ではありません。

私が物事を誤解していない限り、Reportテーブルを正規化してReportLabelID列を作成ReportLabelしてから、個別のラベルを持つテーブルを作成する必要があるようです。次に、上記のクエリのReportLabel代わりにテーブルを配置できます。DISTINCT

また、クエリ全体をパラメーター化して受け入れるなどして、ReportYearサブクエリを排除することもできます。または、テーブルから取得でき、列にインデックスがあると仮定すると、それをシークに変換できる場合があります (これを取得するには、2 つの個別のクエリが必要になる場合があります)。次に、数値テーブルまたは on-the-フライ番号テーブルを使用して、それらの間の一連の年を生成します。BeginYearEndYearMin(ReportYear), Max(ReportYear)

これら 2 つの変更を行うと、クエリのパフォーマンスが大幅に向上します。

于 2013-04-27T00:07:24.643 に答える