我有以下表格
处置表
Dis_ID | OfferID | RequestID
------------------------------------
34564 | 123 | 9
77456 | 123 | 8
25252 | 124 | 7
46464 | 125 | 10
36464 | 125 | 6
35353 | 125 | 5
请求表
RequestID | AccountNum |
---------------------------
5 | 548543 |
6 | 548543 |
7 | 684567 |
8 | 684567 |
9 | 684567 |
10 | 548543 |
11 | 684567 |
排名表
RankID | OfferId | RequestID | Score
-------------------------------------------
34564 | 123 | 11 | 1
77456 | 124 | 11 | 2
25252 | 125 | 11 | 3
使用上面的数据我需要一个查询,其行为如下,给定一个请求号查看排名表中的每个记录,在这个例子中我们有3个(123,124和125)。返回此处已加入帐号的Disposition表中出现次数最少的OfferId。在此示例中,offerId 123对于此帐号出现两次,offerId 124出现一次,offerId 125根本不出现此帐号。所以应该返回offerId 125。除非它们全部相同,否则应始终返回存在于排序表中且在Disposition表中出现次数最少的offerId,然后返回Score字段中具有最低值的offerId。例如,如果在Dispostion表中没有出现offerID,则offerId 123将返回,因为其Score值为1.
结果表看起来像这样
| OfferId | Score | Dis_Occurrences
---------------------------------------------------------------
| 123 | 1 | 2
| 124 | 2 | 1
| 125 | 3 | 0 <--Return this record
这是我到目前为止所拥有的。
SELECT oRank.OfferId, oRank.Rank_Number, count(oRank.OfferId) AS NumDispositions
From Rank oRank
join Request req
on oRank.RequestId = req.RequestId
join Disposition dis
on oRank.OfferId = dis.OfferId
where req.Customer_Account_Number = 684567 and req.RequestId = 11 and oRank.OfferId = dis.OfferId
group by oRank.Rank_Number, oRank.OfferId
order by NumDispositions, oRank.Rank_Number
我的错误结果表看起来像这样
| OfferId | Score | Dis_Occurrences
---------------------------------------------------------------
| 123 | 1 | 2
| 124 | 2 | 1
| 125 | 3 | 3
它计算offerId出现在处置表
中的总次数答案 0 :(得分:1)
编辑 - 根据作者的评论,这是另一个版本:
SQLFiddle中的示例:http://sqlfiddle.com/#!6/d3f99/1/0
with RankReqMap as (
select rnk.OfferId, rnk.Score, reqAcct.AccountNum, reqReq.RequestID
from [Rank] rnk
left join Request reqAcct on reqAcct.RequestID = rnk.RequestID
left join Request reqReq on reqReq.AccountNum = reqAcct.AccountNum
where rnk.RequestID = 11 -- Put your RequestId filter here
)
select oRank.OfferId
,oRank.Score
,count(dis.RequestID) as NumDispositions
from RankReqMap oRank
left join Disposition dis on dis.OfferID = oRank.OfferId
and dis.RequestID = oRank.RequestID
group by oRank.OfferId , oRank.Score
order by NumDispositions, oRank.Score;
原始帖子
SQLFiddle中的示例:http://sqlfiddle.com/#!6/770a8/1/0
此查询假设您已根据OfferID将处置加入排名,因为示例数据中这些表的RequestID不匹配。您可能需要根据自己的需要进行调整,但下面的查询应该会为您提供您正在寻找的记录:
-- Gather base data
with RankData as (
select rnk.RankID
,rnk.OfferID
,rnk.RequestID
,rnk.Score
,Dis_Occurrences = count(dis.OfferID)
from dbo.[Rank] rnk
left join dbo.Disposition dis on dis.OfferID = rnk.OfferId
left join dbo.Request req on req.RequestID = rnk.RequestID
group by rnk.RankID, rnk.OfferID, rnk.RequestID, rnk.Score
)
-- Rank count of Dis_Occurrences, taking lowest score into account as a tie breaker
, DispRanking as (
select rdt.*, Dis_Rank = row_number() over (order by Dis_Occurrences asc, rdt.Score asc)
from RankData rdt
)
-- Return only the value with the highest ranking
select * from DispRanking where Dis_Rank = 1
另请注意,如果将第二个CTE转换为裸SELECT并在结尾处删除SELECT语句,则可以查看所有记录以及它们如何通过row_number()函数进行排名:
-- Gather base data
with RankData as (
select rnk.RankID
,rnk.OfferID
,rnk.RequestID
,rnk.Score
,Dis_Occurrences = count(dis.OfferID)
from dbo.[Rank] rnk
left join dbo.Disposition dis on dis.OfferID = rnk.OfferId
left join dbo.Request req on req.RequestID = rnk.RequestID
group by rnk.RankID, rnk.OfferID, rnk.RequestID, rnk.Score
)
-- Output all values, with rankings
select rdt.*, Dis_Rank = row_number() over (order by Dis_Occurrences asc, rdt.Score asc)
from RankData rdt
祝你好运!
答案 1 :(得分:0)
我认为您可以使用窗口功能:
;with disp as(select offerid, count(*) as ocount
from dispositions group by offerid),
rnk as(select r.offerid,
row_number() over(partition by r.requestid
order by isnull(d.ocount, 0), r.score) rn
from ranks r
left join disp d on r.offerid = d.offerid)
select * from rnk where rn = 1