[英]Picking one row over another
我有一个看起来像这样的表:
ID Type Value
A Z01 10
A Z09 20
B Z01 30
C Z01 40
D Z09 50
E Z10 60
对于每个ID,我想检索一个值。 理想情况下,该值应来自Z01类型的行。 但是,如果Z01不可用,我会选择Z09。 如果没有可用的内容,我什么也不想选择。
结果将如下所示:
Id Type Value
A Z01 10
B Z01 30
C Z01 40
D Z09 50
如何使用T-SQL完成此操作?
这应该给您您想要的:
select *
from table t
where 1 = case
when t.type = 'Z01'
then 1
when t.type = 'Z09'
and not exists (select 1 from table where id = t.id and type = 'Z01')
then 1
else 0
end
使用更通用的方法的另一种方法是(重写CASE
表达式):
select *
from table
where type = 'Z01'
OR (type = 'Z09' and not exists (select 1 from table where id = t.id and type = 'Z01'))
一个显而易见的可sargable
方法(它将使您的查询使用表上适当的索引(如果存在)):
select *
from table
where type = `Z01`
union all
select *
from table
where type = `Z09`
and not exists (select 1 from table where id = t.id and type = 'Z01')
当我说索引时,我指的是type
列上的非聚集索引。
您可以使用这样的查询
;WITH cte
AS (SELECT
*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY type) AS rn
FROM yourtable
WHERE type IN ('Z01', 'Z09'))
SELECT
id, type, value
FROM cte
WHERE rn = 1
我将使用窗口函数:
select t.*
from (select t.*,
row_number() over (partition by id
order by (case when type = 'Z01' then 1
when type = 'Z09' then 2
end)
) as seqnum
from t
) t
where seqnum = 1;
我不完全理解“如果没有可用的东西,那么什么也不要选择”的说法。 如果您是说要“ Z01”,“ Z09”或什么都不想要,请执行以下操作:
select t.*
from (select t.*,
row_number() over (partition by id order by type) as seqnum
from t
where type in ('Z01', 'Z09')
) t
where seqnum = 1;
where
子句进行过滤,您可以按字母顺序对类型进行排序。
然后试试这个
Select distinct a.id,
coalesce(t1.type, t9.type) type,
case when t1.type is not null
then t1.value else t9.value end value
From table a
left join table t1
on t1.id = a.id
and t1.type = 'Z01'
left join table t9
on t9.id = a.id
and t9.type = 'Z09'
Where a.type in ('Z01', 'Z09') -- < -- this last to eliminate row E
像这样:
select distinct
base.Id,
Coalesce(z01.Type, any.Type) Type,
Coalesce(z01.Value, any.Value)
from (select distinct id from [table]) base
left outer join [table] z01
on z01.id = base.id
and z01.Type = 'Z01'
left outer join [table] any
on any.id = base.id
and any.type != 'Z01'
从WHERE
子句开始。 仅选择带有Z01和Z09的条目。 然后使用ROW_NUMBER
对您的行进行排名并保持最佳状态。
select id, type, value
from
(
select
id, type, value,
row_number()
over (partition by id order by case when type = 'Z01' then 1 else 2 end) as rn
from mytable
where type in ('Z01','Z09')
) ranked
where rn = 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.