排序为具有非连续的列值

bqf10yzr  于 2021-06-19  发布在  Mysql
关注(0)|答案(4)|浏览(317)

这在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

提前谢谢。

kxxlusnw

kxxlusnw1#

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

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

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

o7jaxewo

o7jaxewo2#

以下解决方案适用于所有mysql版本,尤其是<8.0版本
在派生表中,首先使用 name 以及 id .
然后,在具有相同属性的所有行中,确定特定行的行号 name 价值观。
现在,使用这个结果集并按行号值对其排序。因此,所有行号为1的行都将排在第一位(对于所有不同的 name 值)等。因此,连续 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小提琴演示

uubf1zoe

uubf1zoe3#

另一个想法。。。

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

f8rj6qna4#

这是我的算法:
计算每个名字的频率
按频率降序和名称排序
切割成与最大频率一样大的分区
每个分区内的行数
按行号和分区号排序
例如:名称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

相关问题