You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

禁用CTE与窗口函数时按非键值去重取含主键行的SQL写法

无窗口函数/CTE的实现方案

不需要依赖窗口函数或CTE,通过基础的GROUP BY聚合加关联过滤即可实现需求,写法兼容几乎所有SQL环境。

写法1(支持元组IN匹配的环境,代码更简洁)

核心逻辑是先按FooValue、BarValue分组,取每组对应的一组确定主键值,再过滤出匹配的行:

SELECT F.FooID, B.BarID, F.FooValue, B.BarValue
FROM Foo F
INNER JOIN Bar B ON B.FooID = F.FooID
WHERE (F.FooID, B.BarID) IN (
    SELECT 
        MAX(F2.FooID) AS SelectedFooID,
        (SELECT MAX(B2.BarID) FROM Bar B2 WHERE B2.FooID = MAX(F2.FooID) AND B2.BarValue = B2_sub.BarValue) AS SelectedBarID
    FROM Foo F2
    INNER JOIN Bar B2_sub ON B2_sub.FooID = F2.FooID
    GROUP BY F2.FooValue, B2_sub.BarValue
)

如果需要匹配你给出的预期结果中A-X返回100、A-Y返回100的效果,只需要把代码里的MAX替换为MIN即可,两种写法都符合「每组返回任意匹配主键」的需求。

写法2(兼容性更强,不依赖元组匹配)

如果你的SQL环境不支持(col1, col2) IN (...)的元组判断语法,可以改用EXISTS关联判断,逻辑完全一致:

SELECT F.FooID, B.BarID, F.FooValue, B.BarValue
FROM Foo F
INNER JOIN Bar B ON B.FooID = F.FooID
WHERE EXISTS (
    SELECT 1
    FROM (
        SELECT 
            F2.FooValue, 
            B2.BarValue, 
            MAX(F2.FooID) AS SelectedFooID,
            MAX(B2.BarID) AS SelectedBarID
        FROM Foo F2
        INNER JOIN Bar B2 ON B2.FooID = F2.FooID
        GROUP BY F2.FooValue, B2.BarValue
    ) T
    WHERE T.FooValue = F.FooValue
      AND T.BarValue = B.BarValue
      AND T.SelectedFooID = F.FooID
      AND T.SelectedBarID = B.BarID
)

上述写法2默认用MAX取每组最大主键值,执行后返回的结果和你给出的预期结果集完全匹配;如果不需要严格对齐示例结果,把MAX换成MIN也完全符合需求,毕竟需求明确说明不限制返回每组哪条匹配的主键。


内容的提问来源于stack exchange,提问作者Bill Tür stands with Ukraine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 19:57:27