首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用sql查询对列表进行排序?

如何使用sql查询对列表进行排序?
EN

Stack Overflow用户
提问于 2019-10-31 18:43:05
回答 2查看 1.2K关注 0票数 0

抽象问题

我有一个sql表,它包含以下形式的记录:

(list_id, value)中,list_id是标识特定列表的整数,而value是有订单的东西。

现在,我很难编写一个sql查询,该查询首先按列表与其他列表的排序顺序返回该表的所有记录,然后按value排序。

抽象的问题是,我想使用sql对列表进行排序。

比较两个列表的算法

比较两个列表的算法如下:

代码语言:javascript
复制
data CompareRes = FirstSmaller | FirstGreater | Equal deriving Show

compareLists :: Ord a => [a] -> [a] -> CompareRes
compareLists [] [] = Equal
-- Longer lists are considered to be smaller
compareLists _ [] = FirstSmaller
compareLists [] _ = FirstGreater
compareLists (x:xs) (y:ys) 
  | x < y = FirstSmaller
  | x > y = FirstGreater
  | otherwise = compareLists xs ys

详细信息

在我的特定情况下,这些值都是Date的。

代码语言:javascript
复制
CREATE TABLE `list_date` (
  `list_id` INT  NOT NULL,
  `date`    DATE NOT NULL,
  PRIMARY KEY (`list_id`, `date`)
);

我使用的是mysql:8.0数据库,所以使用WINDOW-functions的解决方案是可以接受的。

示例

数据

代码语言:javascript
复制
INSERT INTO `list_date` VALUES
   (1, '2019-11-02'), (1, '2019-11-03'), (1, '2019-11-04'), (1, '2019-11-05'), (1, '2019-11-07'), (1, '2019-11-08'), (1, '2019-11-09'),
   (2, '2019-11-01'), (2, '2019-11-03'), (2, '2019-11-04'),
   (3, '2019-11-01'), (3, '2019-11-02'), (3, '2019-11-03'),
   (4, '2019-11-02'), (4, '2019-11-04'), (4, '2019-11-13'), (4, '2019-11-14'),
   (5, '2019-11-03'), (5, '2019-11-04'), (5, '2019-11-05'), (5, '2019-11-10'),
   (6, '2019-11-01'), (6, '2019-11-02'), (6, '2019-11-03'), (6, '2019-11-05');

查询

我真正挣扎的地方是创建一个计算list_rank的表达式

代码语言:javascript
复制
SELECT 
    `list_id`, 
    `date`,
    <PLEASE HELP> as `list_rank`
FROM 
    `list_date`
ORDER BY 
    `list_rank`, `date`;

预期结果

代码语言:javascript
复制
| list_id | date       | list_rank |
|---------|------------|-----------|
| 6       | 2019-11-01 | 1         |
| 6       | 2019-11-02 | 1         |
| 6       | 2019-11-03 | 1         |
| 6       | 2019-11-05 | 1         |
| 3       | 2019-11-01 | 2         |
| 3       | 2019-11-02 | 2         |
| 3       | 2019-11-03 | 2         |
| 2       | 2019-11-01 | 3         |
| 2       | 2019-11-03 | 3         |
| 2       | 2019-11-04 | 3         |
| 1       | 2019-11-02 | 4         |
| 1       | 2019-11-03 | 4         |
| 1       | 2019-11-04 | 4         |
| 1       | 2019-11-05 | 4         |
| 1       | 2019-11-07 | 4         |
| 1       | 2019-11-08 | 4         |
| 1       | 2019-11-09 | 4         |
| 4       | 2019-11-02 | 5         |
| 4       | 2019-11-04 | 5         |
| 4       | 2019-11-13 | 5         |
| 4       | 2019-11-14 | 5         |
| 5       | 2019-11-03 | 6         |
| 5       | 2019-11-04 | 6         |
| 5       | 2019-11-05 | 6         |
| 5       | 2019-11-10 | 6         |

该图像是我的应用程序产生的当前实时结果。目前,排序是使用Java实现的。

编辑

在没有得到更好的答案之后,我实现了@gordon-linoff建议的解决方案:

代码语言:javascript
复制
SELECT 
    `list_id`, 
    `date`
FROM 
    `list_date`
        INNER JOIN (
            SELECT `sub`.`list_id`,
            GROUP_CONCAT(`sub`.`date` ORDER BY `sub`.`date` SEPARATOR '')  as `concat_dates`
            FROM `list_date` as `sub`
            GROUP BY `sub`.`list_id`
        ) `all_dates` ON (`all_dates`.`list_id` = `list_date`.`list_id`)
ORDER BY 
    `all_dates`.`concat_dates`, `date`;

我还创建了一个SQL Fiddle,这样您就可以使用您的解决方案了。

但此解决方案不按预期对列表进行排序,因为较长的列表被认为比较小的列表更大。

因此,我仍然希望收到一种解决100%需求的解决方案:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-31 18:46:39

如果我理解正确,您可以按照连接在一起的日期对列表进行排序:

代码语言:javascript
复制
select ld.*
from list_date ld join
     (select list_id, group_concat(date) as dates
      from ld
      group by list_id
     ) ldc
     on ld.list_id = ldc.list_id
order by ldc.dates, ld.date;
票数 1
EN

Stack Overflow用户

发布于 2019-11-11 19:38:29

因为它是针对MySql 8的,所以窗口函数可以用于此(yay)。

下面是一个查询,它首先计算一些指标,用于计算排名:

代码语言:javascript
复制
SELECT 
 list_id, 
 `date`,
 DENSE_RANK() OVER (ORDER BY ListMinDate ASC, ListCount DESC, ListMaxDate, list_id) AS list_rank
FROM
(
  SELECT 
   list_id,
   `date`,
   COUNT(*) OVER (PARTITION BY list_id) AS ListCount,
   MIN(`date`) OVER (PARTITION BY list_id) AS ListMinDate,
   MAX(`date`) OVER (PARTITION BY list_id) AS ListMaxDate
  FROM list_date
) q
ORDER BY list_rank, `date`

db<>fiddle https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a8ef7d7358b03b4c11ae55c06d0d726a的测试

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58649513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档