我的表Places
包含以下列:
PlaceId CityId Name Postcode
-----------------------------------------
1 1 Place1 NULL
2 1 Place1 10000
3 2 Place1 10300
4 2 Place2 10500
5 3 Place3 NULL
6 3 Place3 NULL
我想要的输出是:
PlaceId CityId Name Postcode
-----------------------------------------
2 1 Place1 10000
3 2 Place1 10300
4 2 Place2 10500
5 3 Place3 NULL
所以,我需要关注:
如果一个城市的CityId
和Name
列重复,那么我需要一行最小PlaceId
。但是,如果两个重复项中的第一个在Postcode
列中具有NULL,并且较大的id在同一列中具有某个值,那么我需要输出中的第二行(例如,具有ID 1和2的行,返回具有id 2的行) 。如果所有重复项在Postcode列中都具有NULL值,则只返回最小PlaceId
(例如,带有id 5和6的行,返回的行带有id 5)
因此,列Postcode
影响最终输出
我试过这样的事:
SELECT
MIN(nm.PlaceId) AS PlaceId,
nm.CityId,
nm.name,
COUNT(*) AS Number
FROM dbo.Place AS nm
GROUP BY
nm.CityId ,
nm.name
我可以解决这个问题,但解决方案并不好,我要求一些漂亮而优雅的解决方案。
答案 0 :(得分:1)
以下查询对您有所帮助:
;WITH Places as
(
select 1 as PlaceId, 1 as CityId, 'Place1' as Name, NULL as Postcode
UNION ALL
select 2, 1, 'Place1', 10000
UNION ALL
select 3, 2, 'Place1', 10300
UNION ALL
select 4, 2, 'Place2', 10300
UNION ALL
select 5, 3, 'Place3', NULL
UNION ALL
select 6, 3, 'Place3', NULL
)
SELECT t2.PlaceId, groups.CityId, groups.Name, t2.Postcode FROM (
select CityId, Name from Places GROUP BY CityId, Name
) groups
CROSS APPLY
(
SELECT TOP(1)
d2.PlaceId, d2.Postcode,
CASE WHEN d2.Postcode IS NOT NULL THEN 1 ELSE 2 END AS RecordPriority
FROM Places d2
WHERE d2.CityId = groups.CityId AND d2.Name = groups.Name
ORDER BY RecordPriority, PlaceId
) t2 ;
或使用与上述ROW_NUMBER()
相同的ORDER BY
:
;WITH Places AS
(
...
),
OrderedPlaces AS
(
SELECT *,
Rn = ROW_NUMBER() OVER
(PARTITION BY CityId, Name
ORDER BY CASE WHEN Postcode IS NOT NULL THEN 1 ELSE 2 END,
PlaceID)
FROM Places
)
SELECT PlaceId, CityId, Name, Postcode
FROM OrderedPlaces
WHERE Rn = 1 ;
答案 1 :(得分:1)
这个怎么样......
CREATE TABLE #PLACES
( PlaceId int, CityId int, Name varchar(50), Postcode varchar(50)
)
INSERT INTO #PLACES (PlaceId, CityId, Name)VALUES(1, 1, 'Place1' )
INSERT INTO #PLACES (PlaceId, CityId, Name, Postcode)VALUES(2, 1, 'Place1','10000' )
INSERT INTO #PLACES (PlaceId, CityId, Name, Postcode)VALUES(3, 2, 'Place1' , '10300')
INSERT INTO #PLACES (PlaceId, CityId, Name, Postcode)VALUES(4, 2, 'Place2','10500' )
INSERT INTO #PLACES (PlaceId, CityId, Name)VALUES(5, 3, 'Place3' )
INSERT INTO #PLACES (PlaceId, CityId, Name)VALUES(6, 3, 'Place3' )
---查询
;WITH CTE_RESULTS AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY CityId, Name ORDER BY Postcode DESC) ROW_NO, PlaceId , CityId, Name, Postcode
FROM #PLACES
)
SELECT * FROM CTE_RESULTS WHERE ROW_NO=1