单个sql查询执行某些组

son*_*nam 7 mysql sql group-by

CREATE TABLE IF NOT EXISTS `projects` (
 `idproject` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `date` datetime NOT NULL,
  `status` enum('new','active','closed') NOT NULL,
  `priority` enum('low','medium','high') NOT NULL,
  PRIMARY KEY (`idproject`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20
Run Code Online (Sandbox Code Playgroud)

以下是一些数据:

 INSERT INTO `projects` (`idproject`, `name`, `date`, `status`, `priority`) VALUES
(1, 'iCompany', '2011-03-23 11:41:44', 'new', 'medium'),
(2, 'John Doe & Co.', '2011-04-09 14:38:04', 'closed', 'low'),
(3, 'ACME, Inc.', '2011-05-21 11:43:11', 'active', 'high'),
(4, 'John Doe & Co.', '2011-03-28 15:19:45', 'active', 'low'),
(5, 'John Doe & Co.', '2011-03-08 15:16:32', 'new', 'low'),
(6, 'ACME, Inc.', '2011-04-05 20:58:42', 'active', 'low'),
(7, 'Mega Corp', '2011-04-21 08:08:53', 'new', 'low'),
(8, 'iCompany', '2011-04-17 08:40:36', 'active', 'medium'),
(9, 'iCompany', '2011-05-18 14:36:48', 'active', 'low'),
(10, 'John Doe & Co.', '2011-04-18 19:08:25', 'new', 'medium'),
(11, 'ACME, Inc.', '2011-05-19 13:11:04', 'active', 'low'),
(12, 'Foo Bars', '2011-03-03 17:19:29', 'new', 'high'),
(13, 'ACME, Inc.', '2011-04-23 20:42:33', 'active', 'medium'),
(14, 'Foo Bars', '2011-05-13 09:18:15', 'active', 'medium'),
(15, 'ACME, Inc.', '2011-03-20 14:37:18', 'new', 'low'),
(16, 'Foo Bars', '2011-04-18 13:46:23', 'active', 'high'),
(17, 'iCompany', '2011-05-31 07:13:32', 'closed', 'low'),
(18, 'Foo Bars', '2011-05-31 15:43:39', 'active', 'low'),
(19, 'John Doe & Co.', '2011-05-28 11:28:32', 'active', 'medium')
Run Code Online (Sandbox Code Playgroud)

我希望获得所有项目的列表: - 以最新(按时间顺序)状态和优先级, - 从第一个和最晚一个条目之间的天数(如果只有一个条目,则为0),您可以忽略小时, - 按优先级排序('高'优先),然后按名称排序, - 没有最新状态为'已关闭'的项目(从结果中省略).

输出应该是:

+---------------+-----------+---------------+----------------+
¦name           ¦total_days ¦latest_status  ¦latest_priority ¦
+---------------+-----------+---------------+----------------+
¦ACME, Inc.     ¦62         ¦active         ¦high            ¦
¦John Doe & Co. ¦81         ¦active         ¦medium          ¦
¦Foo Bars       ¦89         ¦active         ¦low             ¦
¦Mega Corp      ¦0          ¦new            ¦low             ¦
+---------------+-----------+---------------+----------------+
Run Code Online (Sandbox Code Playgroud)

到目前为止,我得写这个:

 SELECT name,status FROM projects  group by name order by priority desc,name
Run Code Online (Sandbox Code Playgroud)

请帮忙?

Joã*_*lva 4

SELECT *
FROM (
  SELECT name, 
    DATEDIFF(MAX(date), MIN(date)) total_days,
    (SELECT tt.status FROM projects tt 
     WHERE t.name = tt.name AND tt.date = MAX(t.DATE)) latest_status,
    (SELECT tt.priority FROM projects tt 
     WHERE t.name = tt.name AND tt.date = MAX(t.DATE)) latest_priority
  FROM projects t
  GROUP BY name 
  ) t
WHERE latest_status != 'closed'
ORDER BY (CASE latest_priority
          WHEN 'high' THEN 0
          WHEN 'medium' THEN 1
          WHEN 'low' THEN 2 
          END), name;
Run Code Online (Sandbox Code Playgroud)
  • 总天数:取DATEDIFFMAX日期MIN,这将为您提供中间的天数;
  • 最新状态:获取该行的日期等于该MAX日期的状态;
  • 最新优先级:获取行日期等于MAX日期的优先级;
  • order by:将每个优先级字符串转换为数值并按其排序。

这是一个sqlfiddle

  • 我倾向于避免使用子查询方法。在这种查询中,最好提取最新的表,然后将主表连接到最新的表。子查询违反了[DRY原则](http://en.wikipedia.org/wiki/Don't_repeat_yourself) (2认同)