跳转至

2308. 按性别排列表格 🔒

难度中等

题目描述

表: Genders

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| user_id     | int     |
| gender      | varchar |
+-------------+---------+
user_id 是该表的主键(具有唯一值的列)。
gender 的值是 'female', 'male','other' 之一。
该表中的每一行都包含用户的 ID 及其性别。
表格中 'female', 'male','other' 数量相等。

 

编写一个解决方案以重新排列 Genders 表,使行按顺序在 'female''other' 和 'male' 之间交替。同时每种性别按照 user_id 升序进行排序。
上述顺序 返回结果表。
返回结果格式如以下示例所示。

 

示例 1:

输入: 
Genders 表:
+---------+--------+
| user_id | gender |
+---------+--------+
| 4       | male   |
| 7       | female |
| 2       | other  |
| 5       | male   |
| 3       | female |
| 8       | male   |
| 6       | other  |
| 1       | other  |
| 9       | female |
+---------+--------+
输出: 
+---------+--------+
| user_id | gender |
+---------+--------+
| 3       | female |
| 1       | other  |
| 4       | male   |
| 7       | female |
| 2       | other  |
| 5       | male   |
| 9       | female |
| 6       | other  |
| 8       | male   |
+---------+--------+
解释: 
女性:ID 3、7、9。
其他性别:ID 1、2、6。
男性:ID 4、5、8。
我们在 'female', 'other','male' 之间交替排列表。
注意,每种性别都是按 user_id 升序排序的。

解法

方法一

思考

需要按性别轮流输出,且同一性别内部按 \(user\_id\) 升序。直接按性别排序会把三类人分成三段,无法交错。

在每种性别内用窗口函数按 \(user\_id\) 编号,再把 female、other、male 映成 \(0,1,2\)。先按组内名次、再按该映射排序,同一名次下三人恰好按题目要求的性别顺序出现。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Write your MySQL query statement below
WITH
    t AS (
        SELECT
            *,
            RANK() OVER (
                PARTITION BY gender
                ORDER BY user_id
            ) AS rk1,
            CASE
                WHEN gender = 'female' THEN 0
                WHEN gender = 'other' THEN 1
                ELSE 2
            END AS rk2
        FROM Genders
    )
SELECT user_id, gender
FROM t
ORDER BY rk1, rk2;

方法二

思考

方法一借助中间表存放两个排序键。窗口函数可直接写在 \(ORDER\ BY\) 中:仍按性别分区、按 \(user\_id\)\(RANK\),再以性别字典序(female、male、other)作为第二键,省去显式 \(CASE\) 与额外一层 \(WITH\)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
SELECT
    user_id,
    gender
FROM Genders
ORDER BY
    (
        RANK() OVER (
            PARTITION BY gender
            ORDER BY user_id
        )
    ),
    2;

评论