2017-08-17 40 views
0
+----------+---------+--------+------+------------+-----------+ 
| PersonID | OrderID | PlanID | Plan | Sdate  | Edate  | 
+----------+---------+--------+------+------------+-----------+ 
| 1  | 1  | 312 | M | 10/14/2016 | 1/30/2017 | 
| 1  | 4  | 125 | A | 10/18/2016 | 2/3/2017 | 
| 1  | 7  | 411 | B | 10/25/2016 | 4/7/2017 | 
| 2  | 1  | 111 | E | 10/31/2016 | 4/21/2017 | 
| 2  | 3  | 312 | M | 11/4/2016 | 4/28/2017 | 
| 2  | 5  | 253 | L | 11/29/2016 | 5/3/2017 | 
| 3  | 1  | 50  | Q | 12/2/2016 | 5/8/2017 | 
| 3  | 2  | 12  | W | 12/8/2016 | 6/8/2017 | 
| 3  | 4  | 312 | M | 12/22/2016 | 6/26/2017 | 
| 3  | 6  | 53  | Z | 12/27/2016 | 7/10/2017 | 
+----------+---------+--------+------+------------+-----------+ 

我需要下面的输出:SELECT列外部施加WHERE滤波器

+----------+------------+-----------+----------+----------+ 
| PersonID | SDateM  | EDateM | MinPlan1 | MinPlan2 | 
+----------+------------+-----------+----------+----------+ 
| 1  | 10/14/2016 | 1/30/2017 | M  | A  | 
| 2  | 11/4/2016 | 4/28/2017 | E  | M  | 
| 3  | 12/22/2016 | 6/26/2017 | Q  | W  | 
+----------+------------+-----------+----------+----------+ 

其中SDateM是SDATE当计划= M,EDateM是EDATE当计划= M,MinPlan1为最小的计划订单ID为一个人。而MinPlan2是一个人的第二最低OrderID的计划。

我在WHERE子句中应用了PlanID = 312,但这限制了我选择MinPlans的能力。我不知道如何编写代码来提取MinPlan1和MinPlan2。

尝试:

SELECT 
    PersonID 
    ,Sdate AS SDateM 
    ,Edate AS EDateM 
    ,MinPlan1 
    ,MinPlan2 
FROM 
    T1 
WHERE 
    1 = 1 
    AND PlanID = 312 

回答

1
CREATE TABLE t_plan 
(personID INT, 
orderID INT, 
planID INT, 
plan_n VARCHAR(20), 
sdate DATE, 
edate DATE 
) 

INSERT INTO t_plan 
VALUES(1,1,312,'M','10/14/2016','1/30/2017'), 
(1,4,125,'A','10/18/2016','2/3/2017'), 
(1,7,411,'B','10/25/2016','4/7/2017'), 
(2,1,111,'E','10/31/2016','4/21/2017'), 
(2,3,312,'M','11/4/2016','4/28/2017'), 
(2,5,253,'L','11/29/2016','5/3/2017'), 
(3,1,50 ,'Q','12/2/2016','5/8/2017'), 
(3,2,12 ,'W','12/8/2016','6/8/2017'), 
(3,4,312,'M','12/22/2016','6/26/2017'), 
(3,6,53 ,'Z','12/27/2016','7/10/2017') 

SELECT personid, 
     MIN(CASE WHEN plan_n = 'M' THEN sdate END) sdateM, 
     MIN(CASE WHEN plan_n = 'M' THEN edate END) edateM, 
     MAX(CASE WHEN rnum = 1 THEN plan_n END) minplan1, 
     MAX(CASE WHEN rnum = 2 THEN plan_n END) minplan2 
    FROM (SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY personid ORDER BY orderid) rnum 
      FROM t_plan 
     ) t 
GROUP BY personid; 

结果

personid sdateM  edateM  minplan1 minplan2 
1   2016-10-14 2017-01-30 M   A 
2   2016-11-04 2017-04-28 E   M 
3   2016-12-22 2017-06-26 Q   W 
1

你可以做到这一点使用row_number和有条件的聚集。

SELECT PersonID 
,MAX(CASE WHEN plan='M' then Sdate END) AS SDateM 
,MAX(CASE WHEN plan='M' then Edate END) AS EDateM 
,MAX(CASE WHEN rnum=1 then plan END) AS MinPlan1 
,MAX(CASE WHEN rnum=2 then plan END) AS MinPlan2 
FROM (SELECT t1.*,row_number() over(partition by personId order by orderId) as rnum 
     FROM T1 
    ) t 
GROUP BY PersonID 
1

我认为有条件的聚集与row_number()组合的伎俩:

select personid, 
     min(case when plan = 'M' then sdate end) as sdateM, 
     min(case when plan = 'M' then edate end) as edateM, 
     max(case when seqnum = 1 then plan end) as plan_1, 
     max(case when seqnum = 2 then plan end) as plan_2 
from (select t1.*, 
      row_number() over (partition by personid order by orderid) as seqnum 
     from t1 
    ) t1 
group by person_id;