使用GROUP BY和条件的SQL查询

时间:2014-06-19 19:52:48

标签: mysql sql group-by

我有一个"股票市场"具有contract值的数据表。我想获得成交量(每天执行的交易数量)和收盘价,收盘价是交易日最后记录的合约价格。

CREATE TABLE IF NOT EXISTS `contracts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `price` decimal(5,2) NOT NULL,
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1502 ;

通过这样的查询,我能够获得我想要的数据(主要是!):

SELECT count(id) as volume, price, DATE(created_at) FROM `contracts` 
GROUP BY DATE(created_at)

但是,我想要收盘价 - 返回的价格是ID最后记录的价格。有没有办法获得price列设置的最后created_at值?

4 个答案:

答案 0 :(得分:1)

SELECT id,
   count(id) AS volume,
   DATE(created_at),
   (SELECT price
      FROM `contracts` as innerContracts
      WHERE innerContracts.id = outerContracts.id
      ORDER BY created_at DESC LIMIT 1)
FROM `contracts` AS outerContracts
GROUP BY DATE(created_at)

答案 1 :(得分:0)

已经有其他几个答案,但这就是我将如何返回指定的结果集,使用"最大的"给定日期的id值是" last"的id。合同。

SELECT d.volume
     , p.price     AS close_price
     , d.created_dt
  FROM ( SELECT MAX(c.id)          AS id
              , COUNT(c.id)        AS volume
              , DATE(c.created_at) AS created_dt
           FROM contracts c
          GROUP BY DATE(c.created_at)
       ) d
  JOIN contracts p
    ON p.id = d.id

大多数工作都是通过内联视图(别名为 d )完成的,这与原始查询类似;这会为每个日期返回一行,以及行数(volume)和"最大的"日期的ID值(id)。

鉴于id是表中的主键,我们可以在JOIN操作中使用它来从合约表中检索行(别名为 p ) ,我们可以检索price列。


另一种选择是使用SELECT列表中的相关子查询,例如

SELECT d.volume
     , ( SELECT p.price
           FROM contracts p
          WHERE p.created_at >= d.created_dt
            AND p.created_at < d.created_dt + INTERVAL 1 DAY
          ORDER BY p.created_at DESC
          LIMIT 1
       ) AS close_price
     , d.created_dt
  FROM ( SELECT COUNT(c.id)        AS volume
              , DATE(c.created_at) AS created_dt
           FROM contracts c
          GROUP BY DATE(c.created_at)
       ) d

在此示例中,我使用created_at列来确定&#34; last&#34;给定日期的合同。 (我们通过按降序排序得到最后一个,然后使用LIMIT子句确保我们返回不超过一行.ORDER BY子句可以很容易地引用p.id而不是p.created_at。)< / p>

答案 2 :(得分:-2)

通过这种方式是不可能的 在其他DBMS中,您必须拥有在GROUP BY clausule

中选择的所有列

试试这个

SELECT volume, price, created_at FROM contracts JOIN ((
    SELECT count(id) as volume, Max(id) maxid FROM `contracts` 
    GROUP BY DATE(created_at)) AS s) ON (s.maxid = contracts.id)

答案 3 :(得分:-2)

一种解决方案是使用子查询来获得该价格

SELECT count(ctr.id) as volume, 
    (SELECT cc.price
        FROM contracts as cc 
        WHERE DATE(cc.created_at) = DATE(ctr.created_at)
        ORDER BY cc.created_at DESC
        LIMIT 1) as price, 
    DATE(ctr.created_at) 
FROM `contracts` as ctr
GROUP BY DATE(ctr.created_at)

编辑:将查询更改为使用LIMIT并选择价格。我使用了ODER BY DESC,因为它会获得最新日期的行。