Mysql 如何搜索所有表记录,如果不存在记录,如何创建新的空记录?

Mysql 如何搜索所有表记录,如果不存在记录,如何创建新的空记录?,mysql,sql,Mysql,Sql,我有一个包含年度和月度销售额的表,但有些月份没有销售额,我需要运行所有表,如果不存在,则创建一个销售额为零的表 这是我的数据库结构 CREATE TABLE `MonthlySales` ( `code` int(8) NOT NULL, `Year` smallint(4) NOT NULL, `Month` tinyint(2) NOT NULL, `SalesQty` varchar(12) NOT NULL, `SalesValue` varchar(12) NOT

我有一个包含年度和月度销售额的表,但有些月份没有销售额,我需要运行所有表,如果不存在,则创建一个销售额为零的表

这是我的数据库结构

CREATE TABLE `MonthlySales` (
  `code` int(8) NOT NULL,
  `Year` smallint(4) NOT NULL,
  `Month` tinyint(2) NOT NULL,
  `SalesQty` varchar(12) NOT NULL,
  `SalesValue` varchar(12) NOT NULL,
  `TValue` varchar(12) NOT NULL,
  `DValue` varchar(12) NOT NULL,
  `CValue` varchar(12) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  ADD PRIMARY KEY (`code`,`Year`,`Month`),
  ADD UNIQUE KEY `Article` (`code`,`Year`,`Month`);

INSERT INTO `MonthlySales` (`code`, `Year`, `Month`, `SalesQty`, `SalesValue`, `TValue`, `DValue`, `CValue`) VALUES
(100000, 2017, 1, '1', '1.6', '', '', '1.11'),
(100000, 2017, 2, '1', '1.6', '', '', '1.11'),
/*Here i need new records with zero values for months 3,4,5,6,7*/
(100000, 2017, 7, '98', '144.2', '', '29.76', '108.78'),
(100000, 2017, 8, '124', '191.65', '', '74.4', '137.64'),
/*Here i need new records with zero values for months 9,10,11*/
(100000, 2017, 12, '7', '11.2', '', '', '7.78'),
(100000, 2018, 1, '2', '3.2', '', '', '2.24'),
(100000, 2018, 3, '4', '6.32', '', '', '4.44'),
(100000, 2018, 4, '8', '12.8', '', '', '8.91'),
(100000, 2018, 9, '18', '28.74', '', '19.2', '19.84'),
(100000, 2018, 10, '19', '30.02', '', '14.22', '20.97'),
(100000, 2018, 11, '2', '3.16', '', '', '2.2'),
(100000, 2018, 12, '2', '3.16', '', '', '2.2'),
(100000, 2019, 1, '14', '22.12', '', '', '15.38'),
(100000, 2019, 2, '8', '12.64', '', '', '8.8'),
(100000, 2019, 6, '47', '74.26', '', '', '51.7'),
(100002, 2017, 1, '14', '54.02', '', '', '41.16'),
(100002, 2017, 2, '12', '46.8', '', '', '35.28'),
/*Here i need new records with zero values for months 3,4 */
(100002, 2017, 5, '20', '78', '', '', '58.8'),
(100002, 2017, 6, '14', '49.92', '', '', '41.16'), 

我需要从2017年到现在的所有年份和月份的。

我们可以编写一个查询,生成我们想要返回的所有行。我们可以使用半笛卡尔积

我们可以从这里开始返回
年份
值:

SELECT y.yyyy
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 ORDER
    BY y.yyyy
然后向另一行源添加一个联接,为每个
年添加
值。我们还可以添加一个过滤器,以便排除具有来自未来日期的
year
month
值的行

大概是这样的:

SELECT y.yyyy
     , m.mm
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 CROSS
  JOIN ( SELECT 1 AS mm 
         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 UNION ALL SELECT 10
         UNION ALL SELECT 11 UNION ALL SELECT 12
       ) m
HAVING CONCAT(y.yyyy,'-',m.mm,'-01') < DATE_FORMAT(NOW(),'%Y-%m-01')
 ORDER
    BY y.yyyy
     , m.mm
如果表
MonthlySales
包含匹配行,并且我们想要识别在
MonthlySales
中没有匹配行的行,我们可以使用相关子查询上不存在的行或反连接模式执行条件测试

SELECT c.code
     , y.yyyy
     , m.mm
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 CROSS
  JOIN ( SELECT 1 AS mm 
         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 UNION ALL SELECT 10
         UNION ALL SELECT 11 UNION ALL SELECT 12
       ) m
 CROSS
  JOIN ( SELECT 100000 AS code
         UNION ALL SELECT 100002
       ) c

    -- ant-join pattern to eliminate rows that have a match in MonthlySales
  LEFT
  JOIN `MonthlySales` s
    ON s.`code`   = c.code 
   AND s.`year`   = y.yyyy 
   AND s.`month`  = m.mm
 WHERE s.`code` IS NULL

HAVING CONCAT(y.yyyy,'-',m.mm,'-01') < DATE_FORMAT(NOW(),'%Y-%m-01')
 ORDER
    BY c.code
     , y.yyyy
     , m.mm

我们可以编写一个查询来生成我们想要返回的所有行。我们可以使用半笛卡尔积

我们可以从这里开始返回
年份
值:

SELECT y.yyyy
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 ORDER
    BY y.yyyy
然后向另一行源添加一个联接,为每个
年添加
值。我们还可以添加一个过滤器,以便排除具有来自未来日期的
year
month
值的行

大概是这样的:

SELECT y.yyyy
     , m.mm
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 CROSS
  JOIN ( SELECT 1 AS mm 
         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 UNION ALL SELECT 10
         UNION ALL SELECT 11 UNION ALL SELECT 12
       ) m
HAVING CONCAT(y.yyyy,'-',m.mm,'-01') < DATE_FORMAT(NOW(),'%Y-%m-01')
 ORDER
    BY y.yyyy
     , m.mm
如果表
MonthlySales
包含匹配行,并且我们想要识别在
MonthlySales
中没有匹配行的行,我们可以使用相关子查询上不存在的行或反连接模式执行条件测试

SELECT c.code
     , y.yyyy
     , m.mm
  FROM ( SELECT 2017 AS `yyyy` UNION ALL SELECT 2018 UNION ALL SELECT 2019 ) y
 CROSS
  JOIN ( SELECT 1 AS mm 
         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 UNION ALL SELECT 10
         UNION ALL SELECT 11 UNION ALL SELECT 12
       ) m
 CROSS
  JOIN ( SELECT 100000 AS code
         UNION ALL SELECT 100002
       ) c

    -- ant-join pattern to eliminate rows that have a match in MonthlySales
  LEFT
  JOIN `MonthlySales` s
    ON s.`code`   = c.code 
   AND s.`year`   = y.yyyy 
   AND s.`month`  = m.mm
 WHERE s.`code` IS NULL

HAVING CONCAT(y.yyyy,'-',m.mm,'-01') < DATE_FORMAT(NOW(),'%Y-%m-01')
 ORDER
    BY c.code
     , y.yyyy
     , m.mm

我不知道“run all table”是什么意思,但数据显示问题通常最好在应用程序代码中处理我知道varchar数据类型不应该出现在这个表中我不知道“run all table”是什么意思,但是数据显示问题通常最好在应用程序代码中处理。我知道varchar数据类型不应该出现在这个表中。我个人不想把它作为一个单独的步骤来处理,以添加缺少的行。但这就是这个答案的作用,因为这就是被问到的问题。我将回到将行放入表的过程。我们可以生成一组完整的行,而不是反连接,而是对rowsource进行外部连接以获取SalesQuantity、salesvalue等。我个人不会将此作为一个单独的步骤,添加缺少的行。但这就是这个答案的作用,因为这就是被问到的问题。我将回到将行放入表的过程。我们可以生成一组完整的行,而不是反连接,而是对rowsource进行外部连接,以获取saleqty、salesvalue等,而不是插入一个子集,然后找出缺少的内容。