使用条件分组
Group by with use of condition
我有如下所示的数据:
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
基于股票名称、单位、类型 ID 组合(按股票名称、单位、类型 ID 分组),如果股票类型有 'pick' 的任何值,则使用该股票编号,否则选择最小的股票编号组合.
我在下面展示了输出应该是什么样子。我知道我可以很容易地按 stockname、units、typeid 进行分组,然后获取 min(stockid) 但我需要先检查是否有任何值为 'pick' 的值,如果是,则选择其他人选择 min(套接字)。我不知道该怎么做。提前谢谢你。
注意:下面的输出是 分组 按股票名称、单位、类型 ID 显示适当的股票 ID。
输出:
stockid stockname units typeid
432 stn433 gl 2
533 stn664 gl 1
655 stn555 gl 3
我正在使用 SQL Server 2016 - TSql。
我没有完全理解这个问题,但我会说你需要使用案例陈述
CASE WHEN stocktype = 'pick' group by.....
ELSE min(sotckid)
END
一种方法使用 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;
没有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
)
你可以用这个。
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
这是一个简单的查询,它得到了想要的结果:
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
这几乎是 sarslan 的答案,但现在我 post 它 :)
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
我有如下所示的数据:
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
基于股票名称、单位、类型 ID 组合(按股票名称、单位、类型 ID 分组),如果股票类型有 'pick' 的任何值,则使用该股票编号,否则选择最小的股票编号组合.
我在下面展示了输出应该是什么样子。我知道我可以很容易地按 stockname、units、typeid 进行分组,然后获取 min(stockid) 但我需要先检查是否有任何值为 'pick' 的值,如果是,则选择其他人选择 min(套接字)。我不知道该怎么做。提前谢谢你。
注意:下面的输出是 分组 按股票名称、单位、类型 ID 显示适当的股票 ID。
输出:
stockid stockname units typeid
432 stn433 gl 2
533 stn664 gl 1
655 stn555 gl 3
我正在使用 SQL Server 2016 - TSql。
我没有完全理解这个问题,但我会说你需要使用案例陈述
CASE WHEN stocktype = 'pick' group by.....
ELSE min(sotckid)
END
一种方法使用 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;
没有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
)
你可以用这个。
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
这是一个简单的查询,它得到了想要的结果:
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
这几乎是 sarslan 的答案,但现在我 post 它 :)
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