SQL查询筛选同Pedido_R下同时含Tipo=C与Tipo=P的日期记录
实现逻辑说明
你当前的查询仅过滤了Tipo为'C'、'P'的记录后直接分组,缺少对同一Pedido_R下Tipo种类的聚合校验,因此会把仅含单种类型的订单也纳入结果,不符合筛选要求。
要实现需求,核心是先识别出同时包含两种Tipo类型的Pedido_R,再基于这批有效订单返回对应数据。
可直接使用的视图代码
以下写法兼容绝大多数SQL数据库环境,通过子查询聚合校验符合要求的订单号:
CREATE VIEW dbo.VW_Restaurante_Pedido_Valido AS SELECT r.Pedido_R, p.Tipo, r.Data FROM dbo.Restaurante r INNER JOIN dbo.Prato p ON r.Prato_R = p.Referencia WHERE p.Tipo IN ('C', 'P') AND r.Pedido_R IN ( -- 筛选同时存在C、P两种类型的订单 SELECT r_sub.Pedido_R FROM dbo.Restaurante r_sub INNER JOIN dbo.Prato p_sub ON r_sub.Prato_R = p_sub.Referencia WHERE p_sub.Tipo IN ('C', 'P') GROUP BY r_sub.Pedido_R -- 去重后Tipo计数为2,即两种类型同时存在 HAVING COUNT(DISTINCT p_sub.Tipo) = 2 ) GROUP BY r.Pedido_R, p.Tipo, r.Data
如果使用的是SQL Server 2008及以上版本、PostgreSQL、MySQL 8.0及以上版本等支持窗口函数的数据库,可以用更简洁的CTE写法,避免重复关联表:
CREATE VIEW dbo.VW_Restaurante_Pedido_Valido AS WITH Pedido_Com_Tipo_Contagem AS ( SELECT r.Pedido_R, p.Tipo, r.Data, COUNT(DISTINCT p.Tipo) OVER (PARTITION BY r.Pedido_R) AS Tipo_Qtd FROM dbo.Restaurante r INNER JOIN dbo.Prato p ON r.Prato_R = p.Referencia WHERE p.Tipo IN ('C', 'P') ) SELECT Pedido_R, Tipo, Data FROM Pedido_Com_Tipo_Contagem WHERE Tipo_Qtd = 2 GROUP BY Pedido_R, Tipo, Data
关键规则校验点
- 用
COUNT(DISTINCT Tipo) = 2作为判断依据,确保每个Pedido_R下同时存在'C'和'P'两种类型,自动排除仅含单种类型的订单 - 完全保留原查询的表关联关系、过滤范围和分组去重逻辑,不会改动原有业务数据的输出规则
- 给表设置了短别名,提升代码可读性,执行效率比多表关联判断的写法更高
内容的提问来源于stack exchange,提问作者André Almeida
相关产品推荐
相关产品推荐

