排序有不连续的列值(Sort to have non-consecutive column valu

2019-11-05 07:05发布

这是可能在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

提前致谢。

Answer 1:

在MySQL 8+,你可以这样做:

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

在早期版本中,你可以使用变量做到这一点。



Answer 2:

另一个想法...

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 |
+----+--------+


Answer 3:

下面的解决方案会为工作所有的MySQL版本 ,特别版<8.0

  • 在派生表 ,第一排序您的实际表,使用nameid
  • 然后,确定用于特定行的行号,具有相同的所有行内的name的值。
  • 现在,用这个结果集和行号值排序。 所以,具有行数= 1的所有的行会首先(对于所有不同的name值(S))等。 因此,连续的name行不会出现。

您可以尝试使用下面的用户定义的会话变量 :

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小提琴DEMO



Answer 4:

这里是我的算法:

  1. 统计每个名字的频率
  2. 为了通过频率下降和名称
  3. 切成一样大的最大频率分区
  4. 在每个分区内的行数
  5. 为了通过行号和分区号

一个例子:名称A,B,C,d,E

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

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

 step 5
 ------
 ABDABEACEACAD

查询:

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子句)和窗函数(聚集OVER )可作为MySQL的8或MariaDB的10.2。 在此之前,你可以撤退到子查询,这将使相同的查询很长,难以辨认,但。 我想你也可以使用变量来代替,不知何故。

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



文章来源: Sort to have non-consecutive column values