You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中获取同时存在于两种类型的排序结果需求及代码求助

筛选同时存在于两种类型的编号的SQL查询优化

先明确你的核心需求:只保留那些同时属于两种类型(对应你代码里的product_id 8和7)的编号,排除仅属于单一类型的编号。

原代码的问题

你当前的SQL里,子查询T和W是完全相同的——都同时包含了product_id 8和7的记录,然后通过T.number = W.number做连接,这本质上是让每个编号和自身匹配,根本无法区分该编号是否同时存在于两种类型中,自然会保留仅属于单一类型的编号。

解决方案

根据你的需求,我提供两种针对性的方案,你可以根据实际场景选择:

方案1:先筛选符合条件的记录,再分组筛选跨类型的编号

如果你的需求是所有满足数量阈值、且同时属于两种类型的编号(不限制每个类型的数量上限),可以用这个方案:

SELECT 
    number,
    -- 分别获取两种类型下的数量总和
    MAX(CASE WHEN product_id = 8 THEN MOST_FREQUENT END) AS super_type_freq,
    MAX(CASE WHEN product_id = 7 THEN MOST_FREQUENT END) AS box_type_freq,
    MAX(MOST_FREQUENT) AS max_val
FROM (
    -- 先获取每个类型+编号组合的数量总和,筛选满足阈值的记录
    SELECT 
        product_id,
        number,
        SUM(quantity) AS MOST_FREQUENT
    FROM bill_details
    WHERE date_status = 1 
      AND product_id IN (8, 7)
    GROUP BY product_id, number
    HAVING SUM(quantity) >= $d_limit_3
) AS sub_query
-- 按编号分组,筛选出同时存在于两种类型的编号
GROUP BY number
HAVING COUNT(DISTINCT product_id) = 2
-- 保持你原来的排序逻辑
ORDER BY 
    CONCAT(LPAD(max_val, 100, '0'), number) DESC,
    number,
    super_type_freq,
    box_type_freq;

方案2:分别获取两种类型的TOP500,再取交集

如果你的需求是先从每种类型里取前500个高频编号,再保留同时出现在两个TOP列表里的编号,这个方案更贴合你原代码里的LIMIT 500逻辑:

SELECT 
    T.number,
    T.MOST_FREQUENT AS super_type_freq,
    W.MOST_FREQUENT AS box_type_freq,
    GREATEST(T.MOST_FREQUENT, W.MOST_FREQUENT) AS max_val
FROM (
    -- 单独获取super类型(product_id=8)的前500个符合条件的编号
    SELECT 
        product_id,
        number,
        SUM(quantity) AS MOST_FREQUENT
    FROM bill_details
    WHERE date_status = 1 
      AND product_id = 8
    GROUP BY product_id, number
    HAVING SUM(quantity) >= $d_limit_3
    ORDER BY SUM(quantity) DESC
    LIMIT 500
) AS T
-- 用INNER JOIN取两个类型TOP列表的交集,只保留同时存在的编号
INNER JOIN (
    -- 单独获取box类型(product_id=7)的前500个符合条件的编号
    SELECT 
        product_id,
        number,
        SUM(quantity) AS MOST_FREQUENT
    FROM bill_details
    WHERE date_status = 1 
      AND product_id = 7
    GROUP BY product_id, number
    HAVING SUM(quantity) >= $d_limit_3
    ORDER BY SUM(quantity) DESC
    LIMIT 500
) AS W ON T.number = W.number
-- 保持原排序逻辑
ORDER BY 
    CONCAT(LPAD(max_val, 100, '0'), T.number) DESC,
    T.number,
    super_type_freq,
    box_type_freq;

关键逻辑说明

  • 两种方案都通过筛选同时存在于两个product_id分组的编号来实现你的需求,排除仅属于单一类型的记录。
  • 方案2的INNER JOIN是取交集的核心:只有同时出现在两个子查询结果里的编号才会被保留,完美匹配你要排除单一类型编号的要求。

内容的提问来源于stack exchange,提问作者user_777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:36:20