2

同様のデータを持つテーブルが 1 つあります。

CustomerID | ProjectID | DateListed | DateCompleted
123456     | 045       | 07-29-2010 | 04-03-2011
123456     | 123       | 10-12-2011 | 11-30-2011
123456     | 157       | 12-12-2011 | 02-10-2012
123456     | 258       | 06-07-2011 | NULL

基本的には、顧客から連絡があり、リストにプロジェクトがあり、それが完了したら完了としてマークします。

私が求めているのは、すべてのプロジェクトの単純な (少なくとも、あなたはそう思うでしょう) カウントであり、以下のような出力が期待されます。

YEAR | TotalListed | TotalCompleted
2010 |       1     |        0
2011 |       3     |        2
2012 |       0     |        1

ただし、2012 年のプロジェクトがリストされていないため、以下のクエリでは 2012 年のカウントが表示されていません。 2010年に完成しました)。

これを行う方法などの提案やヒントをお待ちしています。一時テーブルについて熟考しましたが、それが最善の方法ですか? 私は、私が必要とするものを得るために、何に対してもオープンです!

(コードに見覚えがある場合は、サブクエリを作成するのを手伝ってくれます!メイン クエリ データ変数を使用した MySQLサブクエリ)

SELECT YEAR(p1.DateListed) AS YearListed, COUNT(p1.ProjectID) As Listed, PreQuery.Completed  
FROM(
    SELECT YEAR(DateCompleted) AS YearCompleted, COUNT(ProjectID) AS Completed 
    FROM projects 
    WHERE CustomerID = 123456 AND DateListed >= DATE_SUB(Now(), INTERVAL 5 YEAR) 
    GROUP BY YEAR(DateCompleted)
) PreQuery 
RIGHT OUTER JOIN projects p1 ON PreQuery.YearCompleted = YEAR(p1.DateListed)
WHERE CustomerID = 123456 AND DateListed >= DATE_SUB(Now(), INTERVAL 5 YEAR)
GROUP BY YearListed 
ORDER BY p1.DateListed
4

1 に答える 1

1

テーブル、クエリ、および期待される結果を確認した後、ニーズに合わせてさらに修正されたクエリを見つけたと思います。ただし、既存のクエリをかなり完全に書き直したものですが、指定されたデータでテストしたところ、希望/期待するのと同じ結果が得られました。

SELECT
    years.`year`,
    SUM(IF(YEAR(DateListed) = years.`year`, 1, 0)) AS TotalListed,
    SUM(IF(YEAR(DateCompleted) = years.`year`, 1, 0)) AS TotalCompleted
FROM
    projects
    LEFT JOIN (
        SELECT DISTINCT `year` FROM (
            SELECT YEAR(DateListed) AS `year` FROM projects
            UNION SELECT YEAR(DateCompleted) AS `year` FROM projects WHERE DateCompleted IS NOT NULL
        ) as year_inner
    ) AS years
        ON YEAR(DateListed) = `year`
        OR YEAR(DateCompleted) = `year`
WHERE
    CustomerID = 123456 AND DateListed >= DATE_SUB(Now(), INTERVAL 5 YEAR)
GROUP BY
    years.`year`
ORDER BY
    years.`year`

説明するには、内側のクエリ (エイリアスyear_inner) から始める必要があります。DateListedとのDateCompleted列で年の完全なリストを選択し、それらのリストを選択してエイリアス サブクエリDISTINCTを作成します。yearsこのサブクエリは、データが必要な「年」の完全なリストを取得するために使用されます。このようにすると、カウントとグループ化を伴うサブクエリとは対照的にWHERE、最も外側のクエリで句を定義するだけで済みます (ただし、何千ものレコードで効率が問題になる場合は、いつでもWHERE句を追加できます)。内部クエリにも; または日付列へのインデックス)。

内部クエリを作成したら、orの値を使用projectsして結果のテーブルを結合します。これにより、列も戻すことができます。LEFT JOINDateListed DateCompletedYEAR()null

フィールドの選択ではyear、内部クエリの列を使用して、表示する年の完全なリストを確実に取得します。次に、現在の行の DateListed と DateCompleted のYEAR()値を現在の年と比較します。それらが等しい場合は 1 を追加し、そうでない場合は 0 を追加します。GROUP BY year私たちの場合SUM()、各列のその年のすべての 1 をカウントし、必要な出力を提供します (できれば、もちろん =P)。

于 2012-10-06T01:28:14.713 に答える