7
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

ここにいくつかのデータがあります:

 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')

すべてのプロジェクトのリストが欲しい:-最新の(時系列の)ステータスと優先度、-最初のエントリと最新のエントリの間の日数(エントリが1つしかない場合は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             ¦
+---------------+-----------+---------------+----------------+

これまでのところ、私はこれを書く必要があります:

 SELECT name,status FROM projects  group by name order by priority desc,name

助けてください?

4

2 に答える 2

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;
  • 合計日数:と日付DATEDIFFを取得します。これにより、その間の日数がわかります。MAXMIN
  • 最新のステータス:行の日付が日付と等しいステータスを取得しMAXます。
  • 最新の優先度:行の日付が日付と等しい優先度を取得しMAXます。
  • 並べ替え:各優先度文字列を数値に変換し、並べ替えます。

これがsqlfiddleです。

于 2012-08-20T14:02:01.577 に答える
4

これを試してください:http ://www.sqlfiddle.com/#!2 / b3962 / 1

select p.name, r.total_days, p.status as latest_status, p.priority as latest_priority
from projects p
join 
(
  select name, max(date) as recent_date, datediff(max(date),min(date)) as total_days
  from projects
  group by name
) 
-- recent
r on(r.name,r.recent_date) = (p.name,date)
where p.status not in ('closed')
order by 
         (case latest_priority
          when 'high' then 0
          when 'medium' then 1
          when 'low' THEN 2 
          end), p.name

出力:

|           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 |

(を使用して)もっと短くしたい場合は、次USINGのエイリアスを作成recent_dateしますdatehttp ://www.sqlfiddle.com/#!2/b3962/2

select 

  p.name, r.total_days, p.status as latest_status, p.priority as latest_priority

from projects p
join 
(

  select name, max(date) as date, datediff(max(date),min(date)) as total_days
  from projects
  group by name

) r using(name,date)

where p.status not in ('closed')
order by 
         (case latest_priority
          when 'high' then 0
          when 'medium' then 1
          when 'low' then 2 
          end), p.name

使い方

裏返しに作業します。最初のステップで、最新のものを見つけます。

  select name, max(date) as recent_date, datediff(max(date),min(date)) as total_days
  from projects
  group by name

出力:

|           NAME |                         DATE | TOTAL_DAYS |
--------------------------------------------------------------
|     ACME, Inc. |   May, 21 2011 11:43:11-0700 |         62 |
|       Foo Bars |   May, 31 2011 15:43:39-0700 |         89 |
|       iCompany |   May, 31 2011 07:13:32-0700 |         69 |
| John Doe & Co. |   May, 28 2011 11:28:32-0700 |         81 |
|      Mega Corp | April, 21 2011 08:08:53-0700 |          0 |

最後のステップで、上記の結果をメインテーブルに結合します。

select 

  p.name, r.total_days, p.status as latest_status, p.priority as latest_priority

from projects p
join 
(

  select name, max(date) as date, datediff(max(date),min(date)) as total_days
  from projects
  group by name

) r using(name,date)

where p.status not in ('closed')
order by 
         (case latest_priority
          when 'high' then 0
          when 'medium' then 1
          when 'low' then 2 
          end), p.name

順序をオーバーライドするには、CASEORDERBY句のステートメントを使用します。

出力:

|           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 |
于 2012-08-20T14:18:34.313 に答える