如何按列值排序垂直表并保持m_id分组有序?
实现按指定name的value排序且保持m_id分组的SQL方案
嘿,这个需求我之前也碰到过!核心就是要先按指定name的value给m_id分组排序,同时保持同组的记录不打散,用窗口函数就能轻松搞定,给你一步步拆解:
原始表结构与数据
先确认下你的原始表数据:
| id | m_id | name | value |
|---|---|---|---|
| 1 | 1 | bed | 3 |
| 3 | 1 | bath | 3 |
| 2 | 2 | bed | 4 |
| 3 | 2 | bath | 2 |
核心思路
我们需要先给每个m_id绑定上目标name(比如bed或bath)对应的value,然后用这个绑定值作为主排序键,这样就能保证同m_id的记录排在一起,同时整体按目标name的value降序排列。组内的顺序可以根据需求调整(比如保持bed在前bath在后)。
情况1:按name='bed'的value降序排序
执行以下SQL:
SELECT id, m_id, name, value FROM your_table_name -- 替换成你的实际表名 ORDER BY -- 给每个m_id绑定对应的bed的value,作为主排序键(降序) MAX(CASE WHEN name = 'bed' THEN value END) OVER (PARTITION BY m_id) DESC, -- 组内保持bed在前,bath在后(和你的示例一致) CASE WHEN name = 'bed' THEN 1 ELSE 2 END, -- 可选:如果组内需要按id排序,加上这行 id;
得到的结果正好是你想要的:
| id | m_id | name | value |
|---|---|---|---|
| 2 | 2 | bed | 4 |
| 3 | 2 | bath | 2 |
| 1 | 1 | bed | 3 |
| 3 | 1 | bath | 3 |
情况2:按name='bath'的value降序排序
只需要把SQL里的目标name改成bath即可:
SELECT id, m_id, name, value FROM your_table_name -- 替换成你的实际表名 ORDER BY MAX(CASE WHEN name = 'bath' THEN value END) OVER (PARTITION BY m_id) DESC, CASE WHEN name = 'bed' THEN 1 ELSE 2 END, id;
执行结果如下:
| id | m_id | name | value |
|---|---|---|---|
| 1 | 1 | bed | 3 |
| 3 | 1 | bath | 3 |
| 3 | 2 | bath | 2 |
| 2 | 2 | bed | 4 |
原理说明
MAX(CASE WHEN name = 'bed' THEN value END) OVER (PARTITION BY m_id):这是一个窗口函数,会为每个m_id下的所有记录都计算出该组内name='bed'的value值(因为每个m_id对应唯一的bed记录,用MAX或MIN都可以),这样同组的记录会拥有相同的排序键,自然不会被打散。- 后面的
CASE WHEN是用来控制组内的显示顺序,如果你不需要固定组内顺序,可以去掉这一行,或者换成其他排序条件(比如value DESC)。
内容的提问来源于stack exchange,提问作者Patrioticcow
相关产品推荐
相关产品推荐

