SQL Server如何查询返回MOP字段唯一的不重复数据行?
问题原因
重复行是因为sales表的单条销售明细,关联pmts表时匹配到了同订单下2种不同支付方式的记录,导致行数翻倍。
解决方案
根据报表需求,有两种常用实现方式:
方案1:合并展示所有支付方式(推荐用于报表,不丢支付信息)
不同数据库的字符串聚合语法略有差异:
- MySQL/MariaDB 可使用
GROUP_CONCAT:
SELECT s.indx, S.custid, S.date, S.qty, S.item, S.price, S.extprice, S.salestax, S.linetotal, S.salenbr, C.company, GROUP_CONCAT(DISTINCT P.MOP SEPARATOR ',') AS MOP FROM sales S JOIN cust C ON S.custid = C.custid JOIN pmts P ON S.salenbr = p.salenbr WHERE s.salenbr = 16749 GROUP BY s.indx, S.custid, S.date, S.qty, S.item, S.price, S.extprice, S.salestax, S.linetotal, S.salenbr, C.company
- PostgreSQL/SQL Server 可使用
STRING_AGG:
将上面语句中的GROUP_CONCAT(DISTINCT P.MOP SEPARATOR ',')替换为STRING_AGG(DISTINCT P.MOP, ',') AS MOP即可。
方案2:仅保留任意一种支付方式
如果不需要展示全部支付方式,可通过窗口函数给同销售条目下的支付方式排序取第一条,兼容所有支持窗口函数的主流数据库:
WITH sales_data AS ( SELECT s.indx, S.custid, S.date, S.qty, S.item, S.price, S.extprice, S.salestax, S.linetotal, S.salenbr, C.company, P.MOP, ROW_NUMBER() OVER(PARTITION BY s.indx ORDER BY P.MOP) AS rn FROM sales S JOIN cust C ON S.custid = C.custid JOIN pmts P ON S.salenbr = p.salenbr WHERE s.salenbr = 16749 ) SELECT indx, custid, date, qty, item, price, extprice, salestax, linetotal, salenbr, company, MOP FROM sales_data WHERE rn = 1
如果需要优先取特定支付方式,比如优先保留CC支付的记录,可将窗口函数中的ORDER BY子句修改为ORDER BY CASE WHEN P.MOP = 'CC' THEN 1 ELSE 2 END。
内容的提问来源于stack exchange,提问作者dashley
相关产品推荐
相关产品推荐

