我有一张名为 tblRoutes 的表,其中包含一个来自路径的唯一列表(f = from; t = to):
| fCity | fState | tCity | tState |
|========|========|========|========|
|New York| NY | Miami | CA |
|Houston | TX |New York| NY |
...
然后我有一个名为 tblCarrierRates 的表格,其中列出了运营商为某些路线提供的一系列等级和费率:
| fCity | fState | tCity | tState | Tier | Rate | CarrID | CarrName |
|========|========|========|========|======|======|========|=============|
|New York| NY | Miami | CA | 2 | $2.99| ABCD | Abracadabra |
|New York| NY | Miami | CA | 1 | $3.00| BUMP | Bumpy Rides |
|Houston | TX |New York| NY | 2 | $4.00| SLOW |Slow Carriers|
|Houston | TX |New York| NY | 2 | $4.01| ABCD | Abracadabra |
...
对于 tblRoutes 中列出的每条独特路线,我正在寻找1"最佳"来自 tblCarrierRates 。
"最好的标准"最低 Tier ,其次是最低费率。
结果需要返回 tblCarrierRates 中显示的所有字段,因此根据上面 tblRoutes 中显示的2条路线,所需的结果将是:
| fCity | fState | tCity | tState | Tier | Rate | CarrID | CarrName |
|========|========|========|========|======|======|========|=============|
|New York| NY | Miami | CA | 1 | $3.00| BUMP | Bumpy Rides |
|Houston | TX |New York| NY | 2 | $4.00| SLOW |Slow Carriers|
我看到的方法是按升序排序 Tier 然后 Rate ,然后一些如何匹配fCity,fState的每个唯一组合的TOP 1记录,tCity和tState:
SELECT A.fCity, A.fState, A.tCity, A.tState, Q.Tier, Q.Rate, Q.CarrID, Q.CarrName
FROM tblRoutes As A LEFT JOIN
(SELECT TOP 1 B.CarrID, B.CarrName, B.fCity, B.fState, B.tCity, B.tState, B.Rate, B.Tier
FROM tblCarrierRates As B
ORDER BY tblCarrierRates.Tier ASC, tblCarrierRates.Rate ASC) As Q
ON (A.tState = Q.tState) AND (A.tCity = Q.tCity) AND (A.fState = Q.fState) AND (A.fCity = Q.fCity);
查询不会失败,但正如您可能猜到的那样,我写的子查询(Q)只返回 tblRoutes 中每条路径的单个记录而不是1 ,最终的结果是:
| fCity | fState | tCity | tState | Tier | Rate | CarrID | CarrName |
|========|========|========|========|======|======|========|=============|
|New York| NY | Miami | CA | 1 | $3.00| BUMP | Bumpy Rides |
|Houston | TX |New York| NY | | | | |
......正如你所看到的,休斯顿到纽约没有任何匹配,因为我的子查询只返回1个结果,而不是每个路由1个。
我怎样才能达到我之后的结果?
答案 0 :(得分:3)
我相信您正在寻找与ROW_NUMBER() OVER (PARTITION .. ORDER BY)
类似的Sql Server和Oracle Analytic / Windowing函数,例如like so
虽然这不是在MS Access中直接提供的,但我相信可以通过应用相关子查询来模拟MS Access中的行编号功能,该子查询计算具有相同“分区”的行数(由联接过滤器),并通过计算同一分区中前面行的数量来排序每一行,这些行在订购标准“下方”:
SELECT A.fCity, A.fState, A.tCity, A.tState, Q.Tier, Q.Rate, Q.CarrID, Q.CarrName, TheRank
FROM tblRoutes As A LEFT JOIN
(
SELECT B.CarrID, B.CarrName, B.fCity, B.fState, B.tCity, B.tState, B.Rate, B.Tier,
(
SELECT COUNT(*) + 1
FROM tblCarrierRates rnk
-- Partition Simulation (JOIN)
WHERE B.fCity = rnk.fCity AND B.fState = rnk.fState
AND B.tCity = rnk.tCity AND B.tState = rnk.tState
-- ORDER BY Simulation
AND (rnk.Tier < B.Tier OR
(rnk.Tier = B.Tier AND rnk.Rate < B.Rate))) AS TheRank
FROM tblCarrierRates As B) As Q
ON (A.tState = Q.tState) AND (A.tCity = Q.tCity)
AND (A.fState = Q.fState) AND (A.fCity = Q.fCity)
-- Now, you just want the top rank in each partition.
WHERE TheRank = 1;
只需预先警告性能 - 将为每一行执行子查询。 此外,如果存在关系,则将返回两行。
+1是以行号1开始关闭每个分区(因为其分区中前面的行将为零)
编辑,删除评论
SELECT A.fCity, A.fState, A.tCity, A.tState, Q.Tier, Q.Rate, Q.CarrID, Q.CarrName, TheRank
FROM tblRoutes As A LEFT JOIN
(
SELECT B.CarrID, B.CarrName, B.fCity, B.fState, B.tCity, B.tState, B.Rate, B.Tier,
(
SELECT COUNT(*) + 1
FROM tblCarrierRates rnk
WHERE B.fCity = rnk.fCity AND B.fState = rnk.fState
AND B.tCity = rnk.tCity AND B.tState = rnk.tState
AND (rnk.Tier < B.Tier OR
(rnk.Tier = B.Tier AND rnk.Rate < B.Rate))) AS TheRank
FROM tblCarrierRates As B) As Q
ON (A.tState = Q.tState) AND (A.tCity = Q.tCity)
AND (A.fState = Q.fState) AND (A.fCity = Q.fCity)
WHERE TheRank = 1
答案 1 :(得分:0)
您的内部查询需要按城市和州分组。这将产生每个城市状态1,允许外部联接加入这些字段。
独立调试内部查询,直到您看到外部查询的结果。首先取出Top1,这样你就可以看到排序和分组工作正常。我会明确地将ASC DESC放在你的内部查询中,以便其他人知道你打算在哪个方向上工作。
答案 2 :(得分:0)
您可以尝试以下查询: -
SELECT fCity, fState, tCity, tState, MIN(Tier), MIN(Rate), CarrID, CarrName
FROM tblCarrierRates
GROUP BY fCity, fState, tCity, tState, CarrID, CarrName;