这是在Oracle SQL中。我无法更改表格,只查询已有的表格。
我有一个包含不同类型地址的地址表。主要,邮寄,位置,EOB。我有一张发给不同人的支票表。
Addresses
Group_ID Type
01 Primary
02 Location
02 Primary
03 Mailing
03 EOB
Checks
AMT Group_ID
350.05 01
410.62 02
1.05 03
我有一个优先级列表,将地址类型排序为:Primary,Mailing,EOB,Location。我试图找出如何编写JOIN或WHERE语句,以便我只返回为该组ID列出的最高地址类型的支票。
示例:
AMT Group_ID Type
350.05 01 Primary
410.62 02 Primary
1.05 03 Mailing
等。基本上枚举位置类型并获取MIN值。不幸的是,我无法添加排名列或类似的内容。
答案 0 :(得分:1)
您可以使用ROW_NUMBER()
函数和CASE
语句执行此操作:
;
WITH cte AS (SELECT "AMT"
,a."Group_ID"
,b."Type"
,ROW_NUMBER() OVER(PARTITION BY a."Group_ID"
ORDER BY CASE WHEN b."Type" = 'Primary' THEN 1
WHEN b."Type" = 'Mailing' THEN 2
WHEN b."Type" = 'Location' THEN 3
WHEN b."Type" = 'EOB' THEN 4
ELSE 5
END) AS RN
FROM Checks a
JOIN Addresses b
ON a."Group_ID" = b."Group_ID"
)
SELECT "AMT","Group_ID","Type"
FROM cte
WHERE "RN" = 1
演示:SQL Fiddle
你也可以用同样的方式使用排名功能。
答案 1 :(得分:1)
另一种可能性如下;通过在内部查询中获取MAX()
Type
并加入它。
select c.AMT,
tab."Group_ID",
tab.max_type
from checks c
join
(
select "Group_ID",
max("Type") as max_type
from Addresses
group by "Group_ID"
) tab on c."Group_ID" = tab."Group_ID"
这将导致:
AMT GROUP_ID MAX_TYPE
350 1 Primary
411 2 Primary
1 3 Mailing
答案 2 :(得分:1)
这是@ GoatCO解决方案的一个小变种。我更喜欢它,因为它在 join
之前而不是之后执行分析函数?
SELECT c.amt, c.Group_ID, a.Type
FROM checks c left join
(select a.*,
row_number() over (partition by a.Group_ID
order by (case when a."Type" = 'Primary' then 1
when a."Type" = 'Mailing' then 2
when a."Type" = 'Location' then 3
when a."Type" = 'EOB' then 4
else 5
)
) as seqnum
from addresses a
) a
on c.Group_ID = a.Group_id and a.seqnum = 1;