在SQL Server上,我有以下查询(已最小化):
SELECT A.ID, A.OWNER, B.CAR
FROM TABLE A
LEFT JOIN TABLE B ON A.ID = B.CAR_ID
哪个返回以下内容:
ID Owner Car
01 Bob BMW
02 Bob NULL
03 Bob BMW
04 Andy Audi
05 Andy Audi
我想按第一个非NULL结果对所有者进行分组,以使汽车获得:
Owner Car
Bob BMW
Andy Audi
我可以做到:
SELECT A.OWNER, max(B.CAR) as Car
FROM TABLE A
LEFT JOIN TABLE B ON A.ID = B.CAR_ID
GROUP BY A.OWNER
但是,可以通过Coalesce()来做到这一点吗?还是其他一些可能更适合更复杂的查询?
答案 0 :(得分:1)
我不确定您的意思是第一个结果。如果要按照默认顺序执行,可以执行以下操作: 如果您要按ID订购,那么应该是
SELECT DISTINCT FIRST_VALUE(Owner) OVER(PARTITION BY Owner ORDER BY ID), FIRST_VALUE(Car) OVER(PARTITION BY Owner ORDER BY ID)
FROM Table_Name WHERE Car IS NOT NULL
答案 1 :(得分:1)
如果有汽车,则结果集始终将“ Bob”与“ BMD”关联,并将“ Andy”与“ Audi”关联。但是,我认为在实际数据集中,拥有者可以拥有不止一种类型的汽车。因此,问题就变成了:“您选择哪个?”。
如果它确实是任意的并且无关紧要,那么使用“ max”的现有方法就可以了。至少它具有可预测的默认顺序,因此,如果基表中的数据状态相同,则每次运行都将获得相同的输出。
但是,如果其他东西应该算作“第一”,例如,如果您希望基于“ id”字段进行比较,那么您将要使用“ row_number”在该字段中按顺序排列每个所有者,例如下面的代码。
select owner, car
from (
select *,
ord = row_number() over(partition by owner order by id)
from [Table A] a
left join [Table B] b on a.id = b.car_id
where b.car is not null
) orderings
where ord = 1
答案 2 :(得分:1)
您可以执行以下操作:
SELECT TOP 1 WITH TIES A.OWNER, B.CAR
FROM TABLE A
LEFT JOIN TABLE B ON A.ID = B.CAR_ID
ORDER BY ROW_NUMBER() OVER (PARTITION BY A.OWNER ORDER IIF(B.CAR IS NOT NULL, 0, 1), A.ID)
通过将ORDER BY
分成两部分,放置所有NULL
的最后一个,然后在结果集中按给定的ID排序。每个不同的A.OWNER
都将收到ROW_NUMBER()
1。使用TOP 1 WITH TIES
,您将得到全1,而不使用子查询,因此每个A.OWNER
仅包含一行。