排序以具有非连续的列值

时间:2018-10-23 12:09:56

标签: mysql sql algorithm sorting columnsorting

在mysql查询中可能吗?当前数据表为:

id - fruit - name
1 - Apple - George
2 - Banana - George
3 - Orange - Jake
4 - Berries - Angela

name列中,我想对其进行排序,以便在我的select查询中没有连续的名称。

我希望输出的是名称栏中没有连续的george

id - fruit - name
1 - Apple - George
3 - Orange - Jake
2 - Banana - George
4 - Berries - Angela

谢谢。

4 个答案:

答案 0 :(得分:2)

在MySQL 8+中,您可以执行以下操作:

order by row_number() over (partition by name order by id)

在早期版本中,您可以使用变量来实现。

答案 1 :(得分:1)

以下解决方案适用于all the MySQL versions,尤其是版本<8.0

  • Derived table中,首先使用nameid对实际表进行排序。
  • 然后,确定所有具有相同name值的行中特定行的行号。
  • 现在,使用此结果集并按行号值对其进行排序。因此,所有具有行号= 1 的行都将排在第一位(对于所有不同的name值),依此类推。因此,连续的name行将不会出现。

您可以使用User-defined Session Variables尝试以下操作:

SELECT dt2.id,
       dt2.fruit,
       dt2.name
FROM   (SELECT @row_no := IF(@name_var = dt1.name, @row_no + 1, 1) AS row_num,
               dt1.id,
               dt1.fruit,
               @name_var := dt1.name                               AS name
        FROM   (SELECT id,
                       fruit,
                       name
                FROM   your_table_name
                ORDER  BY name,
                          id) AS dt1
               CROSS JOIN (SELECT @row_no := 0,
                                  @name_var := '') AS user_init_vars) AS dt2
ORDER  BY dt2.row_num,
          dt2.id  

DB Fiddle DEMO

答案 2 :(得分:1)

另一个想法...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,name VARCHAR(12) NOT NULL
);

INSERT INTO my_table VALUES
(1,'George'),
(2,'George'),
(3,'Jake'),
(4,'Angela');

SELECT x.* 
  FROM my_table x
  JOIN my_table y 
    ON y.name = x.name 
   AND y.id <= x.id
 GROUP 
    BY x.id
 ORDER
    BY COUNT(*)
     , id;

+----+--------+
| id | name   |
+----+--------+
|  1 | George |
|  3 | Jake   |
|  4 | Angela |
|  2 | George |
+----+--------+

答案 3 :(得分:0)

这是我的算法:

  1. 计算每个名字的出现频率
  2. 按频率降序排列并命名
  3. 切成与最大频率一样大的分区
  4. 每个分区中的行数
  5. 按行号和分区号排序

一个例子:命名为A,B,C,D,E

fast-deep-equal x 226,960 ops/sec ±1.55% (86 runs sampled)
nano-equal x 218,210 ops/sec ±0.79% (89 runs sampled)
shallow-equal-fuzzy x 206,762 ops/sec ±0.84% (88 runs sampled)
underscore.isEqual x 128,668 ops/sec ±0.75% (91 runs sampled)
lodash.isEqual x 44,895 ops/sec ±0.67% (85 runs sampled)
deep-equal x 51,616 ops/sec ±0.96% (90 runs sampled)
deep-eql x 28,218 ops/sec ±0.42% (85 runs sampled)
assert.deepStrictEqual x 1,777 ops/sec ±1.05% (86 runs sampled)
ramda.equals x 13,466 ops/sec ±0.82% (86 runs sampled)
The fastest is fast-deep-equal

查询:

 step 1 and 2
 ------------
 AAAAABBCCDDEE

 step 3 and 4
 ------------
 12345     
 AAAAA
 BBCCD
 DEE

 step 5
 ------
 ABDABEACEACAD
从MySQL 8或MariaDB 10.2开始,

公用表表达式(with counted as ( select id, fruit, name, count(*) over (partition by name) as cnt from mytable ) select id, fruit, name from counted order by (row_number() over (order by cnt desc, name) - 1) % max(cnt) over (), row_number() over (order by cnt desc, name); 子句)和窗口函数(聚合WITH)可用。在此之前,您可以撤退到子查询,但这会使相同的查询相当长且难以阅读。我想您也可以以某种方式使用变量。

DB小提琴演示:https://www.db-fiddle.com/f/8amYX6iRu8AsnYXJYz15DF/1