SQL:命令创建虚拟行如果不存在

时间:2014-02-12 09:00:11

标签: php mysql sql

如果数据不存在,MySQL可以创建新的虚拟行,具体取决于用户条件吗?
我的查询如下:

 SELECT year, value, type FROM myTable 
 WHERE year BETWEEN ( '2010' AND '2013') AND type IN ('Oil', 'Gas');

输出:

   year | value | type
  ---------------------
   2013  |  0    | Oil
   2012  | 144.5 | Oil
   2012  | 434.3 | Gas
   2011  | 141.0 | Oil
   2011  | 1234  | Gas
   2010  | 4567  | Gas
  ---------------------

我想运行一个会输出如下记录的查询:

    year | value | type
  ---------------------
   2013  |  0    | Oil
   2013  |  0    | Gas  // -> new virtual* row
   2012  | 144.5 | Oil
   2012  | 434.3 | Gas
   2011  | 141.0 | Oil
   2011  | 1234  | Gas
   2010  | 4567  | Gas
   2010  | 0     | Oil // -> new  virtual* row
  ---------------------

用户想要同时显示“Gas”和“Oil”,但是从2013年开始只包含“Oil”类型,所以我想创建“Gas”的新记录,其值为0,然后与'2010'相同(基于上面所需的输出)。

编辑:

   CREATE TABLE `myTable` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `type` varchar(15) DEFAULT NULL,  
   `year` year(4) DEFAULT NULL,
   `value` varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`)
   ) ENGINE=InnoDB AUTO_INCREMENT=92278 DEFAULT CHARSET=latin1

1 个答案:

答案 0 :(得分:1)

如你所说,你实际上有两张桌子。

我不希望用这些0值污染数据库,但是如果你坚持的话。

INSERT INTO data
SELECT
  cross_join.year as year,
  0 as value,
  cross_join.id as type_id
FROM data
RIGHT JOIN (
  SELECT types.id, year
  FROM types
  JOIN (SELECT DISTINCT year FROM data) distinct_years
) cross_join ON (cross_join.id = data.type_id AND cross_join.year = data.year)
WHERE data.year IS NULL

另一种方法是在查询期间虚拟添加这些行,我更喜欢

SELECT
  COALESCE(data.year, cross_join.year) as year,
  COALESCE(data.value, 0) as value,
  COALESCE(data.type_id, cross_join.id) as type_id
FROM data
RIGHT JOIN (
  SELECT types.id, year
  FROM types
  JOIN (SELECT DISTINCT year FROM data) distinct_years
) cross_join ON (cross_join.id = data.type_id AND cross_join.year = data.year);

Demo can be found here.