MySQL,group by 不遵守 order by

MySQL, group by is not respecting order by

我有这个问题

SELECT * FROM ( 
    SELECT 
        wtb_orders.orderid,
        wtb_orders.duration,
        wtb_orders.is_renew,
        wtb_orders.bundle_id,
        wtb_orders.service_id,
        wtb_orders.object_name,
        wtb_orders.pkg_id_fk,
        expires,
        wtb_tokens.disconnect_time
    FROM wtb_orders
    JOIN wtb_tokens ON wtb_orders.orderid=wtb_tokens.orderid
    WHERE 
        wtb_orders.username= "11111111111" AND
        (
            (
                ((expires + INTERVAL 5 DAY) >= NOW()) OR 
                (expires=0 AND wtb_tokens.orderid IS NOT NULL)
            ) OR
            expires=0
        )
    ORDER by expires DESC
) as tmp
GROUP BY 
    tmp.pkg_id_fk, 
    tmp.bundle_id,
    tmp.service_id;

我想按 expires 订购,然后 select 显然 tmp.pkg_id_fk, tmp.bundle_id,tmp.service_id 不为空的商品。

如果 2 件商品具有相同的 bundle_id,例如,我想要 select 日期较近的一件 expires

查询应该有效,如果我不输入 group by 一切都很好,我使用 group by 过滤掉重复项,它决定选择一个旧的过期日期,就好像我没有对它们进行排序。

很抱歉延迟提供示例,这是一个 example

因此,在第一个 select 查询中,我 select 所有内容,在第二个 select 查询中,我使用分组依据,这样您就可以看出区别。看看有 pkg_id_fk = 35

的项目

当我进行分组时,我希望看到最大过期日期的那个,但相反,我看到了另一个。

原因是,假设你买了一个捆绑包,它快要过期了所以你续订了它,现在你有两个重复的捆绑包。我想让你看看最新的

我想分享我在 Reddit 上收到的 GreenPilgrim89 的回答,这是一个绝妙的回答,但我不喜欢在生产中使用它,因为它很老套,除非没有其他选择。他说只需添加限制来执行命令,就可以了!

SELECT * FROM ( 
    SELECT 
        wtb_orders.orderid,
        wtb_orders.duration,
        wtb_orders.is_renew,
        wtb_orders.bundle_id,
        wtb_orders.service_id,
        wtb_orders.object_name,
        wtb_orders.pkg_id_fk,
        expires,
        wtb_tokens.disconnect_time
    FROM wtb_orders
    JOIN wtb_tokens ON wtb_orders.orderid=wtb_tokens.orderid
    WHERE 
        wtb_orders.username= "11111111111" AND
        (
            (
                ((expires + INTERVAL 5 DAY) >= NOW()) OR 
                (expires=0 AND wtb_tokens.orderid IS NOT NULL)
            ) OR
            expires=0
        )
    ORDER by expires DESC LIMIT 1000000 
) as tmp
GROUP BY 
    tmp.pkg_id_fk, 
    tmp.bundle_id,
    tmp.service_id;

有关更多信息,请查看 this 和上面链接的他的 post。