【问题标题】:How to sort a list in descending order along with group by?如何按降序对列表进行排序以及分组依据?
【发布时间】:2020-09-04 00:22:53
【问题描述】:

在 rails 4 应用程序中,我试图通过组合多个表来获取一些数据。

SELECT keywords.name, DATE(keyword_histories.created_at) as c, position, keyword_id FROM 'keyword_histories' join keywords on keywords.id = keyword_histories.keyword_id WHERE (keywords.website_id = 3716 and keyword_histories.status = 'finished') AND ('keyword_histories'.'created_at' BETWEEN '2020-03-16 00:00:00' AND '2020-05-15 00:00:00') GROUP BY DATE(keyword_histories.created_at), keyword_histories.keyword_id ORDER BY keywords.name asc, keywords.id asc, keyword_histories.created_at desc, DATE(keyword_histories.created_at) desc;

这个查询的当前输出是(这里取前几行),

+---------+------------+----------+------------+
| name    | c          | position | keyword_id |
+---------+------------+----------+------------+
| az      | 2020-05-08 |        1 |       3360 |
| bags    | 2020-05-08 |      100 |       3314 |
| bags    | 2020-04-27 |      100 |       3314 |
| bags    | 2020-04-09 |      100 |       3314 |
| bags    | 2020-04-08 |      100 |       3314 |
| battery | 2020-05-08 |      100 |       3337 |
| battery | 2020-04-27 |      100 |       3337 |
| books   | 2020-05-08 |      100 |       3313 |
| books   | 2020-04-27 |      100 |       3313 |
| books   | 2020-04-09 |      100 |       3313 |
| books   | 2020-04-08 |      100 |       3313 |

在为created_at 添加GROUP BY 之前,数据是这样的(c 列已占用时间以便更好地理解),

+---------+---------------------+----------+------------+
| name    | c                   | position | keyword_id |
+---------+---------------------+----------+------------+
| az      | 2020-05-08 11:48:01 |        1 |       3360 |
| az      | 2020-05-08 10:30:06 |        1 |       3360 |
| bags    | 2020-05-08 11:48:01 |       39 |       3314 |
| bags    | 2020-05-08 10:30:06 |       45 |       3314 |
| bags    | 2020-05-08 10:24:21 |       46 |       3314 |
| bags    | 2020-05-08 10:20:16 |       35 |       3314 |
| bags    | 2020-05-08 10:03:55 |      100 |       3314 |
| bags    | 2020-04-27 12:45:20 |      100 |       3314 |
| bags    | 2020-04-09 08:25:20 |      100 |       3314 |
| bags    | 2020-04-09 06:45:48 |      100 |       3314 |
| bags    | 2020-04-08 06:52:08 |      100 |       3314 |
| battery | 2020-05-08 11:48:01 |       14 |       3337 |
| battery | 2020-05-08 10:30:06 |       14 |       3337 |
| battery | 2020-05-08 10:24:21 |       12 |       3337 |
| battery | 2020-05-08 10:20:17 |       12 |       3337 |
| battery | 2020-05-08 10:03:55 |      100 |       3337 |
| battery | 2020-04-27 12:45:20 |      100 |       3337 |

如果没有GROUP BY,它将按desc 的顺序排序。但我的要求是,即使我为DATE(keyword_histories.created_at) 添加GROUP BY,也应使用keyword_histories.created_at 按降序对数据进行排序。

预期的输出应该是,

* With time, added for just to know the `datetime` to sort

+---------+---------------------+----------+------------+
| name    | c                   | position | keyword_id |
+---------+---------------------+----------+------------+
| az      | 2020-05-08 11:48:01 |        1 |       3360 |
| bags    | 2020-05-08 11:48:01 |       39 |       3314 |
| bags    | 2020-04-27 12:45:20 |      100 |       3314 |
| bags    | 2020-04-09 08:25:20 |      100 |       3314 |
| bags    | 2020-04-08 06:52:08 |      100 |       3314 |
| battery | 2020-05-08 11:48:01 |       14 |       3337 |
| battery | 2020-04-27 12:45:20 |      100 |       3337 |


* Without time, exact output required.

+---------+------------+----------+------------+
| name    | c          | position | keyword_id |
+---------+------------+----------+------------+
| az      | 2020-05-08 |        1 |       3360 |
| bags    | 2020-05-08 |       39 |       3314 |
| bags    | 2020-04-27 |      100 |       3314 |
| bags    | 2020-04-09 |      100 |       3314 |
| bags    | 2020-04-08 |      100 |       3314 |
| battery | 2020-05-08 |       14 |       3337 |
| battery | 2020-04-27 |      100 |       3337 |

position 值是根据最新的created_at 显示的主要字段。请帮我解决这个问题。

【问题讨论】:

  • 我不明白。你到底在期待什么?所以你想让最终输出按照created_at的降序排序,还是name升序再created_at降序排序?
  • 应该是 created_at 的顺序。即使名称顺序不存在,也无法根据要求进行排序。
  • 也输出应该像第二个(没有时间)
  • 实际输出中,有bags的记录有4条。在您的预期输出中,只有 3 个。这是为什么呢?
  • 对不起!已更新。

标签: mysql database sorting


【解决方案1】:

如果可以的话,你可以使用嵌套查询。

查看您给出的第二个输出,没有分组,即

+---------+---------------------+----------+------------+
| name    | c                   | position | keyword_id |
+---------+---------------------+----------+------------+
| az      | 2020-05-08 11:48:01 |        1 |       3360 |
| az      | 2020-05-08 10:30:06 |        1 |       3360 |
| bags    | 2020-05-08 11:48:01 |       39 |       3314 |
| bags    | 2020-05-08 10:30:06 |       45 |       3314 |
| bags    | 2020-05-08 10:24:21 |       46 |       3314 |
| bags    | 2020-05-08 10:20:16 |       35 |       3314 |
| bags    | 2020-05-08 10:03:55 |      100 |       3314 |
| bags    | 2020-04-27 12:45:20 |      100 |       3314 |
| bags    | 2020-04-09 08:25:20 |      100 |       3314 |
| bags    | 2020-04-09 06:45:48 |      100 |       3314 |
| bags    | 2020-04-08 06:52:08 |      100 |       3314 |
| battery | 2020-05-08 11:48:01 |       14 |       3337 |
| battery | 2020-05-08 10:30:06 |       14 |       3337 |
| battery | 2020-05-08 10:24:21 |       12 |       3337 |
| battery | 2020-05-08 10:20:17 |       12 |       3337 |
| battery | 2020-05-08 10:03:55 |      100 |       3337 |
| battery | 2020-04-27 12:45:20 |      100 |       3337 |

我不知道你是怎么得到它的。但我假设您对此有疑问。获得此表后,假设此关系的别名为 T,以下查询将提供所需的输出。

select unique_obj.name, unique_obj._date,earlypos.position,unique_obj.id FROM
(
    select T1._date,T2.c,T2.position,T1.id from
    (
        select DATE(c) as _date,max(c) as maxc,id from T 
        GROUP BY DATE(c), id 
    ) T1 join
        (select c,position,id from T) T2
    ON (T1.maxc=T2.c) AND (T1.id=T2.id)
) earlypos JOIN
(
    select name,DATE(c) as _date,id FROM T
    group by name,DATE(c),id
) unique_obj

ON (earlypos._date=unique_obj._date) AND (earlypos.id=unique_obj.id)
ORDER BY unique_obj.name,unique_obj._date desc;

也许,您可以通过使用主查询进一步优化它,但这个可以工作。

earlypos 为每个 c,id 组合获取所需的 position

unique_obj 是表T 的简单投影,具有c,id 组合的唯一值。

我假设对于给定的 cid 值,name 是唯一的。因此,我还将name 放在unique_objgroup by 中。否则它将成为非聚合属性。

我得到的输出是

+---------+------------+----------+------+
| name    | _date      | position | id   |
+---------+------------+----------+------+
| az      | 2020-05-08 |        1 | 3360 |
| bags    | 2020-05-08 |       39 | 3314 |
| bags    | 2020-04-27 |      100 | 3314 |
| bags    | 2020-04-09 |      100 | 3314 |
| bags    | 2020-04-08 |      100 | 3314 |
| battery | 2020-05-08 |       14 | 3337 |
| battery | 2020-04-27 |      100 | 3337 |
+---------+------------+----------+------+

这类似于预期的输出。 如果您有任何问题,请发表评论。

【讨论】:

  • 你能把它转换成我的表名吗?它令人困惑。
  • 给我你用于第二个表的查询。位置为 1 1 39 45 46...
  • 上面提到的查询当前正在使用,第二个表被手动修改以显示所需的输出。
  • 我知道。但我的方法只使用第二个表查询。所以请发送该查询。在聊天中发送。
猜你喜欢
  • 2022-01-06
  • 1970-01-01
  • 2018-05-03
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 2015-08-18
相关资源
最近更新 更多