我看过这里:Selecting all corresponding fields using MAX and GROUP BY和类似的页面,但我似乎无法让我的所有字段正确排列。
我觉得我正处于解决这个问题的风口浪尖,但也许我正走在错误的道路上,需要以不同的方式看待这个问题。
我想要的是合并标志设置为 1 的每个特性名称每个卧室数量租金最低的单元。
我的 SQL fiddle :http://sqlfiddle.com/#!2/881c41/2
上面的图像是通过以下查询获得的:
SELECT ru.id, run.name, ru.rent, ru.bedrooms
FROM rental_units AS ru
JOIN rental_unit_names AS run
on run.id = ru.name_id
WHERE run.merge = 1
ORDER BY run.name ASC, ru.bedrooms ASC, ru.rent ASC
上图是此查询的结果:
SELECT ru.id, run.name, ru.rent, MIN(ru.rent) AS min_rent, ru.bedrooms
FROM rental_units AS ru
JOIN rental_unit_names AS run
on run.id = ru.name_id
WHERE run.merge = 1
GROUP BY ru.name_id, ru.bedrooms
ORDER BY run.name ASC, ru.bedrooms ASC, ru.rent ASC, ru.id ASC
在大多数情况下,一切看起来都很好,直到您查看第 4 行。租金值不一致,id
应该是 6 而不是 5.
下图是我想要的结果。
::编辑1::
我是否需要创建一个包含 2 列的链接表,其中一列中包含租赁单元 ID,另一列中包含租赁单元名称 ID?或者至少以某种方式将其作为派生表来实现?
最佳答案
一般来说,除非您尝试执行某种 MySQL“魔法”,否则您应该始终按 SELECT
中的每个非聚合、非常量列进行分组> 列表。
在您的情况下,最好的方法是获取(名称,# 间卧室,最低租金)列表,然后查找与这些值匹配的所有行 - 换句话说,所有行的(名称,# 间卧室,租金)将列表与最低租金相匹配:
SELECT ru.id, run.name, ru.rent, ru.bedrooms
FROM rental_units ru
JOIN rental_unit_names run ON run.id = ru.name_id
WHERE run.merge = 1
AND (run.name, ru.bedrooms, ru.rent) IN (
SELECT inrun.name, inru.bedrooms, MIN(inru.rent)
FROM rental_units inru
JOIN rental_unit_names inrun ON inrun.id = inru.name_id
WHERE inrun.merge = 1
GROUP BY inrun.name, inru.bedrooms)
此查询将按名称/卧室提供所有最低租金单元。样本数据在几个地方与最低值相关。要仅包含“绑定(bind)”行之一(rental_units.id
最低的行,请尝试此操作 - 唯一的更改是 上的 MIN(ru.id)
第一行并在最后一行添加整体 GROUP BY
:
SELECT MIN(ru.id) AS ru_id, run.name, ru.rent, ru.bedrooms
FROM rental_units ru
JOIN rental_unit_names run ON run.id = ru.name_id
WHERE run.merge = 1
AND (run.name, ru.bedrooms, ru.rent) IN (
SELECT inrun.name, inru.bedrooms, MIN(inru.rent)
FROM rental_units inru
JOIN rental_unit_names inrun ON inrun.id = inru.name_id
WHERE inrun.merge = 1
GROUP BY inrun.name, inru.bedrooms)
GROUP BY run.name, ru.rent, ru.bedrooms
关于MySQL GROUP BY with MIN - 列数据不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17222646/