问题
is this possible in mysql queries? Current data table is:
id - fruit - name
1 - Apple - George
2 - Banana - George
3 - Orange - Jake
4 - Berries - Angela
In the name
column, i would like to sort it so there is no consecutive name on my select
query.
My desires output would be, no consecutive george
in name column.
id - fruit - name
1 - Apple - George
3 - Orange - Jake
2 - Banana - George
4 - Berries - Angela
Thanks in advance.
回答1:
In MySQL 8+, you can do:
order by row_number() over (partition by name order by id)
In earlier versions, you can do this using variables.
回答2:
Another idea...
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:
Following solution would work for all the MySQL versions, especially version < 8.0
- In a Derived table, first sort your actual table, using
name
andid
. - Then, determine the row number for a particular row, within all the rows having same
name
value. - Now, use this result-set and sort it by the row number values. So, all the rows having row number = 1 will come first (for all the different
name
value(s)) and so on. Hence, consecutivename
rows wont appear.
You can try the following using 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
回答4:
Here is my algorithm:
- count each name's frequency
- order by frequency descending and name
- cut into partitions as large as the maximum frequency
- number rows within each partition
- order by row number and partition number
An example: Names A, B, C, D, E
step 1 and 2
------------
AAAAABBCCDDEE
step 3 and 4
------------
12345
AAAAA
BBCCD
DEE
step 5
------
ABDABEACEACAD
The query:
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);
Common table expression (WITH
clauses) and window functions (aggregation OVER
) are available as of MySQL 8 or MariaDB 10.2. Before that you can retreat to subqueries, which will make the same query quite long and hard to read, though. I suppose you could also use variables instead, somehow.
DB fiddle demo: https://www.db-fiddle.com/f/8amYX6iRu8AsnYXJYz15DF/1
来源:https://stackoverflow.com/questions/52948761/sort-to-have-non-consecutive-column-values