如何关联两个无关联的MySQL表并使用GROUP BY date?求实现方案
关联无关联表并按日期分组查询的解决方案
没问题,我来帮你搞定这个需求!首先得明确,既然voucher和ledger没有直接关联字段,我们可以通过日期字段来把它们关联起来,同时按日期分组统计指定时间范围的数据。下面给你两种实用的方案,你可以根据实际情况选择:
方案1:先分别聚合再关联(适合数据量较大的场景)
这种方法先对两个表各自按日期聚合,再通过日期关联,避免大量数据的笛卡尔积,效率更高。假设两个表都有date日期字段和需要统计的amount金额字段(如果你的字段名不同,记得替换成实际名称):
SELECT COALESCE(v.date, l.date) AS date, COALESCE(v.voucher_total, 0) AS voucher_total, COALESCE(l.ledger_total, 0) AS ledger_total FROM ( -- 先聚合voucher表的日期数据 SELECT date, SUM(amount) AS voucher_total FROM voucher WHERE date BETWEEN '2018-01-29' AND '2018-01-31' GROUP BY date ) v LEFT JOIN ( -- 再聚合ledger表的日期数据 SELECT date, SUM(amount) AS ledger_total FROM ledger WHERE date BETWEEN '2018-01-29' AND '2018-01-31' GROUP BY date ) l ON v.date = l.date -- 补充ledger有数据但voucher没有的日期 UNION ALL SELECT COALESCE(l.date, v.date) AS date, COALESCE(v.voucher_total, 0) AS voucher_total, COALESCE(l.ledger_total, 0) AS ledger_total FROM ( SELECT date, SUM(amount) AS voucher_total FROM voucher WHERE date BETWEEN '2018-01-29' AND '2018-01-31' GROUP BY date ) v RIGHT JOIN ( SELECT date, SUM(amount) AS ledger_total FROM ledger WHERE date BETWEEN '2018-01-29' AND '2018-01-31' GROUP BY date ) l ON v.date = l.date WHERE v.date IS NULL
说明:
COALESCE函数用来处理空值,确保某个日期只有单表数据时,另一表的统计值显示为0而不是NULL。LEFT JOIN + RIGHT JOIN + UNION ALL是为了模拟MySQL不支持的FULL JOIN,确保覆盖所有在指定日期范围内有数据的日期。
方案2:合并数据集后再聚合(更简洁易读)
这种方法先把两个表的数据集合并,标记来源后再按日期分组统计,逻辑更直观:
SELECT date, -- 统计voucher表的每日总额 SUM(CASE WHEN source = 'voucher' THEN amount ELSE 0 END) AS voucher_total, -- 统计ledger表的每日总额 SUM(CASE WHEN source = 'ledger' THEN amount ELSE 0 END) AS ledger_total FROM ( -- 合并两个表的数据,标记来源 SELECT date, amount, 'voucher' AS source FROM voucher WHERE date BETWEEN '2018-01-29' AND '2018-01-31' UNION ALL SELECT date, amount, 'ledger' AS source FROM ledger WHERE date BETWEEN '2018-01-29' AND '2018-01-31' ) combined_data GROUP BY date ORDER BY date;
说明:
UNION ALL用来合并两个表的原始数据(不会去重,保留所有记录)。- 用
CASE语句区分不同表的数据,再通过SUM按日期聚合统计。
注意事项
- 确保两个表的日期字段格式一致(都是
DATE类型或可转换为日期的字符串)。 - MySQL中
BETWEEN的日期格式需要用单引号包裹,正确写法是BETWEEN '2018-01-29' AND '2018-01-31',不要用TO。 - 如果你的统计字段不是
amount,或者日期字段不是date,请替换为实际的字段名称。
内容的提问来源于stack exchange,提问作者Livetuts Bj
相关产品推荐
相关产品推荐

