【问题标题】:MySQL, group by is not respecting order byMySQL,group by 不尊重 order by
【发布时间】:2020-06-30 22:15:15
【问题描述】:

我有这个问题

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 订购,然后明确选择tmp.pkg_id_fk, tmp.bundle_id,tmp.service_id 不为空的项目。

如果 2 项具有相同的 bundle_id,例如,我想选择具有较新 expires 日期的一项。

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

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

所以在第一个选择查询中我选择了所有内容,在第二个选择查询中我使用分组依据,这样您就可以看到不同之处。看看有pkg_id_fk = 35的项目

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

原因是,假设您购买了一个捆绑包,它即将过期,所以您更新了它,现在您有两个重复的捆绑包。我想让你看看最新的。

【问题讨论】:

  • 我尝试使用 max、order by 和 group by,它不起作用,我开始在 api 响应中看到max(expires),但除此之外,它什么也没做
  • 你在 group by 之后尝试 order by 吗?
  • @PrakharLondhe 是的,一个选择不是 2 个选择,同样的问题,我只使用了两个选择来尝试强制 mysql 遵守顺序,没有帮助
  • 另外,当您使用 group by 时,您需要在 group by 子句中添加您选择的所有列,如果它们不属于某个聚合函数的一部分。这是你可以在 1000000 个地方找到的东西。这是示例:dbfiddle.uk/…
  • 很明显,您误解了 GROUP BY 和 ORDER BY 的工作方式,并且因为您使用的是旧版本的 mysql,它允许您不包含非聚合列,您会得到奇怪的结果。简而言之。如果您没有使用 SUM()MAX() 等公式聚合列,则必须将其列在您的分组依据中。地球上的所有其他 RDBMS 都会抛出这个 SQL 错误,但旧版本的 mysql 会给你足够的绳索让你上吊。

标签: mysql sql mariadb groupwise-maximum


【解决方案1】:

我想分享我在Reddit 上通过GreenPilgrim89 收到的答案,这是一个绝妙的答案,但我不喜欢在生产中使用它,因为它很hacky,除非没有其他选择。他说只要增加限制来执行命令,它就奏效了!

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 和上面链接的他的帖子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-14
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 2012-05-06
    相关资源
    最近更新 更多