mysql - 使用 GROUP BY 时选择与有序条件匹配的行
问题描述
我有一个房地产属性的 MySQL 数据库。一些属性被列出了不止一次,并带有不同的信息。以下是一些简化的数据:
+--------------+---------+-----------------+------------------------+
| category | price | address | remarks |
+--------------+---------+-----------------+------------------------+
| Commercial | 435000 | 1224 81ST AVE | Great retail space! |
| Multi Family | 435000 | 1224 81ST AVE | Motivated seller! |
| Residential | 435000 | 1224 81ST AVE | 0% down financing |
| Residential | 1095000 | 3290 NW BLUE LN | An exciting new… |
| Land | 150000 | 3878 COHO CIR | Build your dream home… |
| Residential | 540000 | 3918 COHO CIR | Ultra-efficient home… |
| Land | 300000 | 3890 COHO CIR | Light-filled condo… |
| Multi Family | 300000 | 3890 COHO CIR | Light-filled condo… |
+--------------+---------+-----------------+------------------------+
数据库中重复的属性可以通过price
和address
列来标识;在上面的示例数据中,前三行和最后两行是重复的属性。
GROUP BY price, address
为每个属性只返回一行很容易使用。但我需要为每个组获取行category
,Residential
然后Commercial
,然后Multi Family
,最后Land
。换句话说,我想要 where category=Residential
if that exists 的行,否则 wherecategory=Commercial
等。
结果应该是:
+--------------+---------+-----------------+------------------------+
| category | price | address | remarks |
+--------------+---------+-----------------+------------------------+
| Residential | 435000 | 1224 81ST AVE | 0% down financing |
| Residential | 1095000 | 3290 NW BLUE LN | An exciting new… |
| Land | 150000 | 3878 COHO CIR | Build your dream home… |
| Residential | 540000 | 3918 COHO CIR | Ultra-efficient home… |
| Multi Family | 300000 | 3890 COHO CIR | Light-filled condo… |
+--------------+---------+-----------------+------------------------+
在 mysql < 5.7 的旧时代,我可以通过扩展使用他们的非标准组,在 GROUP BY 选择行之前应用排序,如下所示:
SELECT * FROM properties
GROUP BY price, address
ORDER BY FIELD(category, 'Residential', 'Commercial', 'Multi Family', 'Land')
这不再起作用,因为排序是在应用 GROUP BY 之后应用的,所以选择的行是任意的。
有许多问题和答案通过使用聚合函数来解决排序的 GROUP BY 子句的替代方案,但我找不到任何关于我的用例的讨论,其中基于自定义排序函数选择行。
有没有办法在纯 MySQL 中做到这一点?注意:我使用的是 MariaDB 10.1,它没有row_number()
.
解决方案
您可以使用row_number()
:
select p.*
from (select p.*,
row_number() over (partition by price, address order by field(category, 'Residential', 'Commercial', 'Multi Family', 'Land')) as seqnum
from properties p
) p
where seqnum = 1;
你也可以这样做:
select p.*
from products p
where field(category, 'Residential', 'Commercial', 'Multi Family', 'Land') =
select field(p2.category, 'Residential', 'Commercial', 'Multi Family', 'Land')
from products p2
where p2.price = p.price and p2.address = p.address
order by 1
limit 1
);
但 。. . 你真的应该升级到更新版本的 MariaDB。
推荐阅读
- ios - 以编程方式针对 UIView 上的 safeAreaLayoutGuide 设置约束
- python - 无法验证数字是否已在列中
- r - 来自 data.table 的样本
- javascript - 如何隐藏一个元素并且仍然能够转换它并且里面还有一些粘性的东西?
- jquery - 如何绕过 event.stopPropagation 来触发事件
- google-cloud-platform - 如何在气流命令行上创建谷歌云平台连接?
- c# - 如何翻译基于鼠标拖动的旋转脚本以使用触摸输入?
- javascript - 推送通知未定义的“showNotification”
- primefaces - 如何默认设置 xhtml 面板切换?
- ios - 使用 Swift 从 HealthKit 获取过去 30 天的 bodyMass 数据