0

我正在尝试编写一个查询,其中所有建筑物都将在每个日期显示,并为不存在的建筑物列出零。下面是我的示例的示例表和数据。

CREATE TABLE IF NOT EXISTS `table1` (
  `id` int(6) unsigned NOT NULL,
  `buildings` char(3) NOT NULL,
  `date` varchar(50) NOT NULL,
  `sold` char(1) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `table1` (`id`, `buildings`, `date`, `sold`) VALUES
  ('1', '1', '2019-04-22 07:40:08','X'),
  ('2', '1', '2019-04-22 07:41:15',''),
  ('3', '1', '2019-04-22 07:42:10','X'),
  ('4', '3', '2019-04-22 07:43:50','X'),
  ('5', '1', '2019-04-22 07:44:27',''),
  ('6', '2', '2019-05-21 06:43:17','X'),
  ('7', '2', '2019-05-21 07:36:17',''),
  ('8', '1', '2019-05-21 06:32:22','X'),
  ('9', '3', '2019-05-21 07:43:50',''),
  ('10', '2', '2019-05-21 07:44:27','X');

下面列出了我现在使用的 SQL 查询。用于构建第一列的 CONCAT 和 MID 获取一年中的年份和星期以每周创建一个 4 位代码。

SELECT CONCAT(MID(date,3,2),
           LPAD(WEEK(CONCAT(MID(date,1,4),'-',
           MID(date,6,2),'-',
           MID(date,10,2))),2,0)) AS YearWeek, 
       buildings, 
       COUNT(sold) AS count 
FROM table1 
WHERE sold = 'X' 
GROUP BY CONCAT(MID(date,3,2),
           LPAD(WEEK(CONCAT(MID(date,1,4),'-',
           MID(date,6,2),'-',
           MID(date,10,2))),2,0)),
         buildings

我的问题是我得到如下数据

YearWeek    buildings   count
1913        1           2
1913        3           1
1917        1           1
1917        2           2

事实上,我希望数据看起来像下面这样我可以绘制它。

YearWeek    buildings   count
1913        1           2
1913        2           0
1913        3           1
1917        1           1
1917        2           2
1917        3           0

为了实现这一点,我尝试对子查询进行左连接(从 table1 中选择不同的建筑物作为建筑物),但这不起作用,我认为这是因为我按 YearWeek 分组然后构建而不是反过来。

对此查询的任何帮助将不胜感激!

4

1 回答 1

3

您可以通过获取CROSS JOIN不同的值YearWeekbuildings值中的 a 来获得所需的结果,以获取每个值的所有可能组合,然后使用LEFT JOIN表中的 a 来获取该buildings周销售的每种类型的计数。例如:

SELECT yw.YearWeek,
       b.buildings,
       COALESCE(SUM(t.sold = 'X'), 0) AS count
FROM (SELECT DISTINCT buildings
      FROM table1) b
CROSS JOIN (SELECT DISTINCT RIGHT(YEARWEEK(date),4) AS YearWeek
            FROM table1) yw
LEFT JOIN table1 t ON t.buildings = b.buildings AND RIGHT(YEARWEEK(t.date),4) = yw.YearWeek
GROUP BY yw.YearWeek, b.buildings

输出:

YearWeek    buildings   count
1916        1           2
1916        2           0
1916        3           1
1920        1           1
1920        2           2
1920        3           0

dbfiddle 上的演示

注意我使用 MySQL 的内置YEARWEEK函数来简化查询,如果不合适,您可以简单地替换您的公式。

于 2019-05-30T23:08:43.907 回答