iT邦幫忙

0

[已解決]請問DB某月份資料記錄0筆,SQL要怎強制顯示該月份為0呢?

  • 分享至 

  • twitterImage

https://ithelp.ithome.com.tw/upload/images/20210316/20053001g2NAMno2WK.jpg
請問上圖DB資料,青茶沒有2月的記錄
那麼SQL查詢時要怎麼產生 青茶2月是0的內容呢?
像下圖這樣
https://ithelp.ithome.com.tw/upload/images/20210316/20053001der6V7NQb8.jpg
謝謝解答

MySQL: IFNULL
MSSQL : ISNULL
ninja iT邦研究生 2 級 ‧ 2021-03-16 13:47:18 檢舉
謝謝
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
koro_michael
iT邦新手 2 級 ‧ 2021-03-16 12:12:54
最佳解答

MySQL版本,可參考

思路:

  1. 產生需要月份的 table(可以用臨時表),這邊直接抓表中的(不嚴謹,因為表沒有就會少日期)
  2. 產生需要產品的 table(可以用臨時表),這邊直接抓表中的(不嚴謹,因為表沒有就會少產品)
  3. 將上述兩張 table join 就可以得到需要的報表項目(日期 + 產品)
  4. 對數量 table left join,再判斷如果是 null 就給 0
SELECT 
    name_table.`name`,
    month_table.`date`,
    IFNULL(demo.`count`, 0) AS `count`
FROM
    (
		SELECT 
			`date`
		FROM
			demo
		GROUP BY `date`
    ) month_table
    INNER JOIN
    (
		SELECT 
			`name`
		FROM
			demo
		GROUP BY `name`
    ) name_table
    LEFT JOIN
		demo ON 
			month_table.`date` = demo.`date` AND 
            name_table.`name` = demo.`name`
ORDER BY 
	name_table.`name`,
    month_table.`date`
CREATE TABLE `demo` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `date` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `count` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `demo` VALUES (1,'紅茶','2020-01',800),(2,'紅茶','2020-02',750),(3,'紅茶','2020-03',900),(4,'綠茶','2020-01',900),(5,'綠茶','2020-02',850),(6,'綠茶','2020-03',900),(7,'青茶','2020-01',700),(8,'青茶','2020-03',900);

https://ithelp.ithome.com.tw/upload/images/20210316/20135412BQCcoGP9Mg.png

有幫助到你請給個最佳解答

ninja iT邦研究生 2 級 ‧ 2021-03-16 13:48:42 檢舉

謝謝解答,原來要用虛擬table方式來join,筆記筆記

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-03-16 10:50:35

看錯題目了
自刪

不是一個欄位 NULL 要顯示成 0
而是「少了一筆資料」要補進去
青茶 2021-02 0

我不會
/images/emoticon/emoticon25.gif

ninja iT邦研究生 2 級 ‧ 2021-03-16 13:47:45 檢舉

謝謝回覆XD

1
rogeryao
iT邦超人 8 級 ‧ 2021-03-16 12:59:42
CREATE TABLE TableX(
A text(20), -- 品名
B text(20), -- 月份
C int);     -- 銷售量

INSERT INTO TableX (A,B,C) values 
('紅茶','2021-01',800),
('紅茶','2021-02',750),
('紅茶','2021-03',900),
('綠茶','2021-01',900),
('綠茶','2021-02',850),
('綠茶','2021-03',900),
('青茶','2021-01',700),
('青茶','2021-03',900);
CREATE TABLE TableY(
A text(20)); -- 品名

INSERT INTO TableY (A) values 
('紅茶'),
('綠茶'),
('青茶'),
-- 額外增加
('烏龍茶');
-- MySQL 8
SELECT TempK.A AS '品名',TempM.MonthID AS '月份',IFNULL(TableX.C, 0) AS '銷售量'
FROM (
WITH RECURSIVE cte_count (n) 
AS (
      SELECT 1
      UNION ALL
      SELECT n + 1 
      FROM cte_count 
      WHERE n < 12
    )
SELECT n,
CONCAT('2021-',LPAD(CONCAT(n, ''),2,0)) AS 'MonthID'
FROM cte_count
-- 計算到 3 月
WHERE n<=3
) AS TempM
LEFT JOIN (
SELECT A 
FROM TableY
) AS TempK ON 1=1
LEFT JOIN TableX ON TableX.B=TempM.MonthID AND TableX.A=TempK.A
ORDER BY TempK.A,TempM.MonthID
-- 非 MySQL 8
SELECT TempK.A AS '品名',TempM.MonthID AS '月份',IFNULL(TableX.C, 0) AS '銷售量'
FROM (
-- 計算到 3 月
SELECT '2021-01' AS 'MonthID'
UNION
SELECT '2021-02' AS 'MonthID'
UNION
SELECT '2021-03' AS 'MonthID'
) AS TempM
LEFT JOIN (
SELECT A 
FROM TableY
) AS TempK ON 1=1
LEFT JOIN TableX ON TableX.B=TempM.MonthID AND TableX.A=TempK.A
ORDER BY TempK.A,TempM.MonthID

Demo

ninja iT邦研究生 2 級 ‧ 2021-03-16 13:50:17 檢舉

謝謝解答,因為另一位大師先回覆了,所以選先回覆的當最佳解答

我要發表回答

立即登入回答