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

SQL Server主从表查询:强制单明细且筛选子表记录数=1

筛选子表记录数为1的主从表关联数据

嘿,我来帮你搞定这个SQL查询需求!你需要连接主表BILL_INFO和子表BILL_INFO_DETAIL,并且只保留那些子表中对应记录数恰好为1的主表数据。基于你已有的基础SQL,我给你提供两种常用的实现方式:

方法1:子查询 + GROUP BY + HAVING

这种方法先通过子查询统计每个主表分组对应的子表记录数,筛选出记录数=1的分组,再和原表关联获取详细数据:

SELECT 
    bi.BILL_NUMBER, 
    bi.BILL_DATE, 
    bid.SERVICE_CODE, 
    bid.SERVICE_FEE, 
    bid.REQUESTED_QUANTITY 
FROM dbo.BILL_INFO bi
INNER JOIN dbo.BILL_INFO_DETAIL bid 
    ON bi.BILL_NUMBER = bid.BILL_NUMBER 
    AND bi.PAY_MODE_ID = bid.PAY_MODE_ID 
    AND bi.CASHIER_ID = bid.CASHIER_ID -- 补全你未写完的连接条件
INNER JOIN (
    -- 子查询:统计每个主表分组的子表记录数,筛选出数量为1的
    SELECT 
        BILL_NUMBER, 
        PAY_MODE_ID, 
        CASHIER_ID
    FROM dbo.BILL_INFO_DETAIL
    GROUP BY BILL_NUMBER, PAY_MODE_ID, CASHIER_ID
    HAVING COUNT(*) = 1
) AS detail_counts 
    ON bi.BILL_NUMBER = detail_counts.BILL_NUMBER 
    AND bi.PAY_MODE_ID = detail_counts.PAY_MODE_ID 
    AND bi.CASHIER_ID = detail_counts.CASHIER_ID

说明:

  • 子查询detail_counts负责统计每个主表主键组合(BILL_NUMBER、PAY_MODE_ID、CASHIER_ID)对应的子表记录数,通过HAVING COUNT(*) = 1筛选出符合条件的分组。
  • 再将主表、子表和这个统计结果关联,就能得到仅对应子表1条记录的详细数据。

方法2:窗口函数(更简洁高效)

如果你使用的SQL版本支持窗口函数(比如SQL Server 2008及以上),可以用COUNT(*) OVER()来直接计算每个主表分组的子表记录数,然后筛选数量=1的记录:

SELECT 
    BILL_NUMBER, 
    BILL_DATE, 
    SERVICE_CODE, 
    SERVICE_FEE, 
    REQUESTED_QUANTITY 
FROM (
    SELECT 
        bi.BILL_NUMBER, 
        bi.BILL_DATE, 
        bid.SERVICE_CODE, 
        bid.SERVICE_FEE, 
        bid.REQUESTED_QUANTITY,
        -- 窗口函数:计算当前主表分组下的子表总记录数
        COUNT(*) OVER (PARTITION BY bi.BILL_NUMBER, bi.PAY_MODE_ID, bi.CASHIER_ID) AS detail_count
    FROM dbo.BILL_INFO bi
    INNER JOIN dbo.BILL_INFO_DETAIL bid 
        ON bi.BILL_NUMBER = bid.BILL_NUMBER 
        AND bi.PAY_MODE_ID = bid.PAY_MODE_ID 
        AND bi.CASHIER_ID = bid.CASHIER_ID -- 补全连接条件
) AS temp
WHERE temp.detail_count = 1

说明:

  • 内层查询通过PARTITION BY按主表的主键组合分组,用COUNT(*) OVER()计算每个分组的子表记录数,命名为detail_count。
  • 外层查询直接筛选detail_count = 1的记录,就能得到目标结果,这种写法不需要额外的关联,代码更简洁。

你可以根据自己的SQL版本和实际表结构(比如补全未写完的CASHIER_xxx连接条件)来选择合适的方法~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:16:50