SQL group by嵌套的select语句

时间:2017-03-18 21:48:38

标签: sql sql-server database

我的数据如下所示,此处为google spread sheet

enter image description here

我希望选中所有行,并添加一个额外的行,即项目的生命周期(每个item_code),以周为单位,即DATEDIFF(day, min(txn_date), txn_date)/7

我试过这样的事情:

SELECT txn_date, txn_qty, item_code, 
         ( SELECT  DATEDIFF(day, min(txn_date), txn_date)/7
                FROM my_table
                WHERE item_code like 'X6%'
                GROUP BY item_code
            )  weeks_life
          FROM my_table
         WHERE item_code like 'X6%'

对于输出,它应该如下所示: enter image description here

3 个答案:

答案 0 :(得分:1)

我会为此使用DATEDIFF和MAX OVER子句。

declare @TEMP table (transaction_id int, txn_date date, txn_qty int, code char(5))

INSERT INTO @TEMP VALUES ( 1,'2016-09-20',1,'X6113')
INSERT INTO @TEMP VALUES ( 2,'2016-09-22',4,'X6113')
INSERT INTO @TEMP VALUES ( 3,'2016-11-08',7,'X6117')
INSERT INTO @TEMP VALUES ( 4,'2016-12-10',3,'X6117')
INSERT INTO @TEMP VALUES ( 5,'2016-12-22',1,'X6112')
INSERT INTO @TEMP VALUES ( 6,'2017-01-19',2,'X6118')
INSERT INTO @TEMP VALUES ( 7,'2017-02-11',4,'X6119')
INSERT INTO @TEMP VALUES ( 8,'2016-06-30',1,'X6117')
INSERT INTO @TEMP VALUES ( 9,'2016-08-03',5,'X6110')
INSERT INTO @TEMP VALUES (10,'2016-09-11',7,'X6118')
INSERT INTO @TEMP VALUES (11,'2016-10-29',1,'X6110')
INSERT INTO @TEMP VALUES (12,'2016-11-12',335,'X6113')
INSERT INTO @TEMP VALUES (13,'2017-01-06',1,'X6110')
INSERT INTO @TEMP VALUES (14,'2017-02-06',12,'X6113')


select transaction_id
      ,txn_date
      ,DATEDIFF(WEEK,MIN(txn_date) OVER(PARTITION BY code order by code),txn_date)  as life_weeks
      ,txn_qty
      ,code
from @TEMP

来自MSDN的参考资料

答案 1 :(得分:0)

如果你想使用这样的内联子查询,你可以这样做:

select 
    txn_date
  , txn_qty
  , item_code
  , ceiling((
  datediff(day, (
        select min(txn_date)
        from t i
        where i.item_code = t.item_code
      ), txn_date)
    ) / 7.0) as weeks_life
from t
where item_code like 'X6%'
order by 
    item_code
  , txn_date

cross apply()版本:

select 
    txn_date
  , txn_qty
  , item_code
  , ceiling((datediff(day, x.min_txn_date, txn_date)) / 7.0) as weeks_life
from t
  cross apply (
    select min_txn_date = min(txn_date)
    from t i
    where i.item_code = t.item_code
    ) as x
where item_code like 'X6%'
order by 
    item_code
  , txn_date

inner join版本:

select 
    t.txn_date
  , t.txn_qty
  , t.item_code
  , ceiling((datediff(day, x.min_txn_date, t.txn_date)) / 7.0) as weeks_life
from t
  inner join (
    select min_txn_date = min(txn_date), item_code
    from t i
    group by item_code
    ) as x 
    on x.item_code = t.item_code
where t.item_code like 'X6%'
order by 
    t.item_code
  , t.txn_date

rextester演示:http://rextester.com/BYTL99094

返回:

+------------+---------+-----------+------------+
|  txn_date  | txn_qty | item_code | weeks_life |
+------------+---------+-----------+------------+
| 2016-08-03 |       5 | X6110     |          0 |
| 2016-10-29 |       1 | X6110     |         13 |
| 2017-01-06 |       1 | X6110     |         23 |
| 2016-12-22 |       1 | X6112     |          0 |
| 2016-09-20 |       1 | X6113     |          0 |
| 2016-09-22 |       4 | X6113     |          1 |
| 2016-11-12 |     335 | X6113     |          8 |
| 2017-02-06 |      12 | X6113     |         20 |
| 2016-06-30 |       1 | X6117     |          0 |
| 2016-11-08 |       7 | X6117     |         19 |
| 2016-12-10 |       3 | X6117     |         24 |
| 2016-09-11 |       7 | X6118     |          0 |
| 2017-01-19 |       2 | X6118     |         19 |
| 2017-02-11 |       4 | X6119     |          0 |
+------------+---------+-----------+------------+

答案 2 :(得分:0)

您可以使用窗口功能。我想这就是你想要的:

SELECT txn_date, txn_qty, item_code, 
       DATEDIFF(day,
                MIN(txn_date) OVER (PARTITION BY item_code),
                txn_date
               )/7 as weeks_life
FROM my_table
WHERE item_code like 'X6%';