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

SQL使用Having子句未返回结果,三表条件查询求助

问题分析与修正方案

首先咱们先把你的需求拆解清楚,确保理解到位:
你需要返回所有满足以下任一条件的AccountNo:

  • 该账号不在Givers表中;
  • 该账号在Givers表中,同时满足:
    1. TakeMoney表中该账号在'10-10-2020'的sum(MoneyTaken) 小于 Yateem表中该账号的sum(Money)*3;
    2. TakeMoney的记录日期匹配'10-10-2020';

你的原SQL存在几个关键问题,导致没返回预期结果:

  1. 主表选得不对:原SQL以Givers为主表做左连接,直接漏掉了"不在Givers表中"的账号;
  2. 聚合函数用错了:把需求里的sum(Yateem.Money)*3写成了COUNT(Yateem.Money)*3,完全偏离了计算逻辑;
  3. 子查询没关联当前账号:子查询里没指定AccountNo和外层查询关联,算出来的是所有账号的总和,不是当前账号的;
  4. 过滤条件位置错了:HAVING子句里的COUNT(Yateem.Money) >0过滤掉了Yateem中无记录的Givers账号,不符合需求;
  5. 日期匹配方式不严谨:如果date是日期类型,用LIKE不如直接用=准确(如果是字符串类型可以保留LIKE)。

修正后的SQL语句

下面是符合需求的SQL,我会把逻辑拆解得明明白白:

-- 先获取所有可能的AccountNo:涵盖Givers、Yateem、TakeMoney里的所有账号
WITH AllAccounts AS (
    SELECT AccountNo FROM Givers
    UNION
    SELECT AccountNo FROM Yateem
    UNION
    SELECT AccountNo FROM TakeMoney
),
-- 预计算每个账号在Yateem中的总金额
YateemTotal AS (
    SELECT 
        AccountNo,
        COALESCE(SUM(Money), 0) AS TotalYateemMoney
    FROM Yateem
    GROUP BY AccountNo
),
-- 预计算每个账号在2020-10-10的TakeMoney总金额
TakeMoneyTotal AS (
    SELECT 
        AccountNo,
        COALESCE(SUM(MoneyTaken), 0) AS TotalTaken
    FROM TakeMoney
    WHERE date = '10-10-2020' -- 如果date是字符串类型,用LIKE也可,但=更精准
    GROUP BY AccountNo
)
SELECT aa.AccountNo
FROM AllAccounts aa
LEFT JOIN Givers g ON aa.AccountNo = g.AccountNo
LEFT JOIN YateemTotal yt ON aa.AccountNo = yt.AccountNo
LEFT JOIN TakeMoneyTotal tmt ON aa.AccountNo = tmt.AccountNo
WHERE 
    -- 条件1:账号不在Givers表中
    g.AccountNo IS NULL
    OR
    -- 条件2:账号在Givers表中,且满足sum(MoneyTaken) < sum(Money)*3
    (
        g.AccountNo IS NOT NULL
        AND tmt.TotalTaken < yt.TotalYateemMoney * 3
        -- 确保该账号在TakeMoney中有2020-10-10的记录
        AND tmt.AccountNo IS NOT NULL
    );

关键逻辑说明
  1. AllAccounts CTE:通过UNION收集所有出现过的AccountNo,确保不会漏掉不在Givers里的账号;
  2. YateemTotal和TakeMoneyTotal CTE:提前算好每个账号的聚合值,避免重复计算,逻辑也更清晰;
  3. WHERE条件:明确拆分两个需求分支,每个条件都精准匹配:
    • 第一个分支直接判断账号不在Givers中;
    • 第二个分支先确认账号在Givers中,再判断TakeMoney总金额小于Yateem总金额的3倍,同时确保该账号在TakeMoney中有指定日期的记录;

如果你的date字段是日期类型,建议把'10-10-2020'改成数据库支持的标准日期格式(比如'2020-10-10'),避免格式匹配出问题。

内容的提问来源于stack exchange,提问作者SomeOne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:27:51