SQL技术问询:如何筛选PAK为'T'且对应MNO拥有至少3个不同PNO的记录
解决你的SQL查询需求
首先,我先明确你的核心需求:从emq表中检索所有满足以下条件的行:
- 记录的
PAK字段值为'T'; - 该记录对应的
MNO,在所有PAK='T'的记录中拥有至少3个不同的PNO值。
你的原SQL问题分析
你之前的语句存在几个关键问题:
- 字段名称笔误:原表中并没有
HAYMNO字段,你应该是想写MNO; - COUNT函数用法错误:
COUNT(DISTINCT 字段1, 字段2)这种写法是无效的,COUNT的DISTINCT参数只能接收单个字段或表达式; - 逻辑冗余复杂:多次JOIN的方式不仅容易引发重复记录,还完全没必要——我们只需要先锁定符合条件的
MNO,再关联获取对应记录即可。
正确的SQL解决方案
这里提供两种简洁高效的实现方式:
方法1:子查询筛选符合条件的MNO(最直观)
SELECT mno, pno, pak FROM emq WHERE pak = 'T' AND mno IN ( -- 先找出所有满足"PAK='T'且至少有3个不同PNO"的MNO SELECT mno FROM emq WHERE pak = 'T' GROUP BY mno HAVING COUNT(DISTINCT pno) >= 3 );
逻辑说明:
- 子查询部分:按
MNO分组,仅统计PAK='T'的记录,筛选出不同PNO数量≥3的MNO; - 主查询:直接取出这些
MNO对应的所有PAK='T'的记录,正好匹配你想要的结果(MNO=33的三条记录)。
方法2:窗口函数实现(更高效,适合大数据量)
如果你使用的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),可以用这种一次扫描完成的写法:
SELECT mno, pno, pak FROM ( SELECT mno, pno, pak, -- 按MNO分区,计算每个MNO下PAK='T'的不同PNO数量 COUNT(DISTINCT pno) OVER (PARTITION BY mno) AS distinct_pno_count FROM emq WHERE pak = 'T' ) AS sub_query WHERE distinct_pno_count >= 3;
逻辑说明:
- 内层查询用窗口函数
COUNT(DISTINCT pno) OVER (PARTITION BY mno),直接计算每个MNO对应的不同PNO数量; - 外层筛选出数量≥3的记录,得到最终结果。
修正你的测试语句
你之前的测试语句修正笔误后应该写成:
-- 查看MNO=33的PAK='T'的所有不同PNO SELECT DISTINCT pno FROM emq WHERE pak='T' AND mno=33;
如果要统计数量,正确写法是:
SELECT mno, COUNT(DISTINCT pno) AS pno_count FROM emq WHERE pak='T' AND mno=33 GROUP BY mno;
这样就能正确得到MNO=33的不同PNO数量是3。
内容的提问来源于stack exchange,提问作者msadasjwd
相关产品推荐
相关产品推荐

