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

如何基于多表数据查询本月过期卡片最多的县?

查询本月过期卡片数量最多的区县

表结构

  • Customer表:cnp, customer_no(客户编号), city(城市), county(区县)
  • Accounts表:account_number(账户编号), customer_no(客户编号), balance(余额)
  • Cards表:card_id(卡片ID), account_number(账户编号), card_number(卡号), exp_date(过期日期)

需求

查询本月过期卡片数量最多的区县(COUNTY)

尝试的SQL语句

SELECT TOP 1 Customer.county, COUNT(Customer.county) AS county_count
FROM Customer
JOIN Accounts ON Customer.customer_no = Accounts.customer_no
JOIN Cards ON Accounts.account_number = Cards.account_number
WHERE Cards.exp_date BETWEEN DATEADD(month, -1, GETDATE()) AND GETDATE()
GROUP BY Customer.county
ORDER BY county_count DESC;

问题分析

原SQL的日期条件逻辑有误:DATEADD(month, -1, GETDATE()) AND GETDATE() 筛选的是过去30天左右的过期卡片,而非当前自然月的过期卡片。比如当前是10月15日,这个条件会包含9月15日-10月15日的卡片,不符合"本月过期"的需求。

另外,用COUNT(Customer.county)统计可能存在误差——如果某条Customer记录的county为空,会被排除在统计外,改用卡片ID统计更准确。

修正后的SQL语句

写法1:精准匹配年月

SELECT TOP 1 c.county, COUNT(cd.card_id) AS expired_card_count
FROM Customer c
JOIN Accounts a ON c.customer_no = a.customer_no
JOIN Cards cd ON a.account_number = cd.account_number
WHERE YEAR(cd.exp_date) = YEAR(GETDATE()) 
  AND MONTH(cd.exp_date) = MONTH(GETDATE())
GROUP BY c.county
ORDER BY expired_card_count DESC;

写法2:日期范围(索引友好)

如果Cards.exp_date字段建有索引,推荐用日期范围写法,让索引正常生效,提升查询性能:

SELECT TOP 1 c.county, COUNT(cd.card_id) AS expired_card_count
FROM Customer c
JOIN Accounts a ON c.customer_no = a.customer_no
JOIN Cards cd ON a.account_number = cd.account_number
WHERE cd.exp_date >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)
  AND cd.exp_date < DATEADD(month, 1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
GROUP BY c.county
ORDER BY expired_card_count DESC;

补充说明

  • 表别名的使用让SQL更简洁易读
  • 用COUNT(cd.card_id)确保统计的是实际过期的卡片数量,避免因county字段为空导致的统计偏差
  • 两种写法都能精准筛选当前自然月内过期的卡片,可根据实际索引情况选择

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:31:42