0

しばらくの間、これを整理しようとしています。助けていただければ幸いです。

それぞれ日付値と整数値を持つ2つの列を取得しているこのテーブルがあります。問題は、int 値が null の場合は常に mysql が日付値をスキップすることです。

ここでSQLステートメント

SELECT DATE_FORMAT(sales_date_sold, '%b \'%y')
    AS sale_date, sales_amount_sold 
    AS sale_amt 
    FROM yearly_sales 
    WHERE sales_date_sold BETWEEN DATE_SUB(SYSDATE(), INTERVAL 2 YEAR) AND SYSDATE() 
    GROUP BY YEAR(sales_date_sold), MONTH(sales_date_sold) 
    ORDER BY YEAR(sales_date_sold), MONTH(sales_date_sold) ASC;

2011 年 2 月には値がないため、その月は他のいくつかの月とともにスキップされます。合体と if_null も機能しません。

4

4 に答える 4

1

ディメンション内のすべての月の値を提供する行ソースが必要であり、それに対して yearly_sales テーブルを左結合します。

GROUP BY を実行している場合、メジャー (sales_amount_sold) の集計が必要な場合、または GROUP BY が不要な場合があります。(あなたの質問のクエリは、特定の月に1行だけのsales_amount_soldから値を返します。それはあなたが望むものかもしれませんが、返すのは非常に奇妙な結果セットです。)


1 つの方法は、返されるすべての月の DATE 値を含む「calendar_month」テーブルを用意することです。(これを生成する方法は他にもあります。stackoverflow の他の場所にある質問に対する既存の回答)

SELECT m.month                            AS sale_date
     , IFNULL(SUM(s.sales_amount_sold),0) AS sale_amt
  FROM calendar_months m
  LEFT
  JOIN yearly_sales s
    ON s.sales_date_sold >= m.month 
   AND s.sales_date_sold < DATE_ADD(m.month,INTERVAL 1 MONTH)
 WHERE m.month BETWEEN DATE_SUB(SYSDATE(), INTERVAL 2 YEAR) AND SYSDATE()
 GROUP BY m.month
 ORDER BY m.month

このクエリはわずかに異なる結果を返します。sale_date の WHERE 句が現在の日時の 2 年前を参照しているため、元のクエリのように部分的な月を含めるのではなく、「月全体」のグループでのみ行を取得します。 、2年前の「月の最初」ではなく。

calendar_months テーブルは必ずしも必要ではありません。これは、行ソースを返すクエリに置き換えることができます。その場合、月の値の述語を外部クエリからサブクエリに移動できます。


補遺: calendar_month テーブルを行ソースとして使用する場合は、返される可能性のあるすべての「月」の値をテーブルに入力する必要があります。

CREATE TABLE calendar_month
(`month` DATE NOT NULL PRIMARY KEY COMMENT 'one row for first day of each month');

INSERT INTO calendar_month(`month`) VALUES ('2011-01-01'),('2011-02-01'),('2011-03-01') 

別の方法として、テーブル参照ではなく、動的に生成された行ソースをインライン ビューとして指定できます。(同様のクエリを使用して、calendar_months テーブルにすばやくデータを入力できます。)

このクエリを括弧で囲み、前に提供したクエリの間に貼り付けることができFROMますcalendar_months

SELECT DATE_ADD('1990-01-01',INTERVAL 1000*thousands.digit + 100*hundreds.digit + 10*tens.digit + ones.digit MONTH) AS `month`
  FROM ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) ones
  JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) tens
  JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) hundreds
  JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) thousands
于 2012-06-26T18:00:45.750 に答える
1

問題は、値が NULL であることではなく、データベースからデータを選択していることです。特定の月のデータがない場合、MySQL にはそこにないデータを選択する方法がありません。

MySQLでこれを完全に解決する唯一の方法は、非常によく似た質問ですでに回答されています

于 2012-06-26T18:01:14.307 に答える
0

以前にタイムスタンプでこの問題が発生しました。私が使用した解決策は、すべての月を含む参照テーブルを作成することでした. これは、1 ~ 12 の数字 (12 行) だけの表にすることも、さらに一歩進んで月の名前を入れることもできます。次にyearly_sales、テーブルをテーブルに参加させて、1_through_12毎月取得することができます。

于 2012-06-26T18:00:24.980 に答える
0

NULL の代わりに 0 を使用しないのはなぜですか?

于 2012-06-26T18:02:40.420 に答える