JOIN两表后如何分组查询以仅显示唯一OrderId?
要解决重复OrderId的问题,核心是既要保留通过OrderItem表校验DiscountAmountInclTax=0.0000的逻辑,又要确保每个订单只返回一条记录。这里有几种实用的方案:
方案1:用DISTINCT快速去重
因为你选择的所有字段都来自Order表,重复的行内容完全一致,直接在SELECT后加DISTINCT就能快速去除重复记录:
SELECT DISTINCT a.[Id], CustomerId, OrderTotal, ShippingMethod, AffiliateId, OrderDiscount, OrderSubTotalDiscountInclTax FROM [Order] a JOIN OrderItem b ON a.Id = b.OrderId WHERE AffiliateId = 11 AND b.DiscountAmountInclTax = 0.0000 AND OrderSubTotalDiscountInclTax = 0.0000 AND OrderDiscount = 0.0000 AND OrderStatusId = 30 AND CreatedOnUtc > '2018-07-01' ORDER BY a.Id DESC
这个方法改动最小,适合快速调整原查询。
方案2:用EXISTS子查询(性能更优)
如果OrderItem表数据量较大,EXISTS会比JOIN后去重的性能更好——它直接检查订单是否存在符合条件的订单项,不会生成大量中间重复行:
SELECT a.[Id], CustomerId, OrderTotal, ShippingMethod, AffiliateId, OrderDiscount, OrderSubTotalDiscountInclTax FROM [Order] a WHERE AffiliateId = 11 AND OrderSubTotalDiscountInclTax = 0.0000 AND OrderDiscount = 0.0000 AND OrderStatusId = 30 AND CreatedOnUtc > '2018-07-01' AND EXISTS ( SELECT 1 FROM OrderItem b WHERE b.OrderId = a.Id AND b.DiscountAmountInclTax = 0.0000 ) ORDER BY a.Id DESC
EXISTS的逻辑是“只要找到一个匹配的订单项就停止查询”,避免了JOIN带来的冗余数据处理,在大数据场景下优势明显。
方案3:用GROUP BY分组(扩展性强)
如果后续需要对OrderItem的字段做聚合统计(比如统计每个订单的订单项数量),可以用GROUP BY,把Order表的所有字段都放在GROUP BY子句中:
SELECT a.[Id], CustomerId, OrderTotal, ShippingMethod, AffiliateId, OrderDiscount, OrderSubTotalDiscountInclTax FROM [Order] a JOIN OrderItem b ON a.Id = b.OrderId WHERE AffiliateId = 11 AND b.DiscountAmountInclTax = 0.0000 AND OrderSubTotalDiscountInclTax = 0.0000 AND OrderDiscount = 0.0000 AND OrderStatusId = 30 AND CreatedOnUtc > '2018-07-01' GROUP BY a.[Id], CustomerId, OrderTotal, ShippingMethod, AffiliateId, OrderDiscount, OrderSubTotalDiscountInclTax ORDER BY a.Id DESC
这个方案和DISTINCT效果类似,但扩展性更强,适合未来需要添加聚合字段的场景。
总结
如果只是单纯去重,DISTINCT最简洁;如果追求性能,优先选EXISTS;如果需要后续扩展聚合逻辑,GROUP BY更合适。
内容的提问来源于stack exchange,提问作者vbDoug
相关产品推荐
相关产品推荐

