按条件分组

时间:2017-09-13 10:53:57

标签: sql sql-server tsql sql-server-2016

我有如下数据:

    stockid     stockname   units   typeid   stocktype
    321         stn433      gl      2        
    433         stn433      gl      2
    432         stn433      gl      2         pick
    544         stn664      gl      1         
    533         stn664      gl      1
    655         stn555      gl      3         pick
    677         stn555      gl      3

根据stockname,units,typeid组合(按stockname,units,typeid分组),如果stocktype有任何'pick'值,请使用该stockid或者选择组合的最小stockid。

我在下面显示了输出应该是什么样子。我知道我可以通过stockname,units,typeid轻松做一组,然后得到min(stockid)但是我需要检查是否有任何值'pick',如果是这样选择其他人选择min(sotckid) 。我无法弄清楚如何做到这一点。提前谢谢。

注意:下面的输出是分组由stockname,units,typeid显示相应的stockid。

输出:

    stockid     stockname   units   typeid
    432         stn433      gl      2
    533         stn664      gl      1
    655         stn555      gl      3 

我正在使用SQL Server 2016 - TSql。

6 个答案:

答案 0 :(得分:1)

你可以使用它。

DECLARE @SampleData TABLE(stockid INT, stockname VARCHAR(10), units VARCHAR(20), typeid INT, stocktype VARCHAR(20) )

INSERT INTO @SampleData VALUES
    (321         ,'stn433','gl',      2, NULL),        
    (433         ,'stn433','gl',      2, NULL),
    (432         ,'stn433','gl',      2, 'pick'),
    (544         ,'stn664','gl',      1, NULL),         
    (533         ,'stn664','gl',      1, NULL),
    (655         ,'stn555','gl',      3, 'pick'),
    (677         ,'stn555','gl',      3, NULL)


;WITH PickTable AS (
    SELECT MIN(stockid) stockid, stockname,   units,   typeid  FROM @SampleData
    WHERE stocktype ='pick'
    GROUP BY stockname,   units,   typeid
)
,NotPickTable
AS (
    SELECT MIN(stockid) stockid, stockname,   units,   typeid  FROM @SampleData T
    WHERE NOT EXISTS(SELECT * FROM PickTable P WHERE P.stockname = T.stockname AND P.units= T.units AND  P.typeid = T.typeid )
    GROUP BY stockname,   units,   typeid
)
SELECT * FROM PickTable
UNION 
SELECT * FROM NotPickTable

答案 1 :(得分:0)

我没有完全理解这个问题,但我会说你需要使用案例陈述

     CASE WHEN stocktype = 'pick' group by.....
     ELSE min(sotckid)
     END

答案 2 :(得分:0)

一种方法使用row_number()

select t.*
from (select t.*,
             row_number() over (partition by stockname, units, typeid
                                order by (case when stocktype = 'pick' then 1 else 2 end)
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

答案 3 :(得分:0)

没有CASE

的解决方案
SELECT * FROM stack WHERE stocktype = 'pick'
UNION ALL
SELECT * FROM stack
WHERE stockid IN
(
   SELECT MIN(stockid) FROM stack 
   WHERE stockname NOT IN (
     SELECT stockname FROM stack WHERE stocktype = 'pick'
   )
   GROUP BY stockname
)

答案 4 :(得分:0)

这是一个简单的查询,可获得所需的结果:

select case when IsPick is NULL then minStockId else StockId end AS stockid,
       stockname, units, typeid
from (
    select  min(stocktype) AS IsPick, 
            max(case when stocktype is not null then stockid end) AS StockId,
            min(stockid) AS minStockId,
            stockname,
            units,
            typeid
    from @x
    group by  stockname, units, typeid
) AS A

答案 5 :(得分:0)

这几乎是sarslan的答案,但现在我发布了它:)

with data as(
SELECT [Stockid]
  ,[StockName]
  ,[units]
  ,[typeid]
  ,[stocktype]
  ,case when stocktype IS not null then 1 else 0 end as Flag
FROM [LegOgSpass].[dbo].[stock]
)

,picks as (
select min([Stockid]) as StockID
  ,[StockName]
  ,[units]
  ,[typeid]
  from data
  where Flag = 1
  group by Stockname,units,typeid
 )


,nopicks as (
select MIN(a.stockid) as Stockid,a.StockName,a.Units,a.typeid from data  a 
where a.Flag= 0 and not exists (select typeid from picks b where a.typeid = 
b.typeid)


group by a.stockname,a.units,a.typeid
)
Select * from picks
union all
select * from nopicks