MySQL 查询:限制 JOIN

Posted

技术标签:

【中文标题】MySQL 查询:限制 JOIN【英文标题】:MySQL Query: LIMITing a JOIN 【发布时间】:2010-09-14 20:22:08 【问题描述】:

假设我有两个要加入的表。 分类:

id   name
----------
1    Cars
2    Games
3    Pencils

还有物品:

id   categoryid   itemname
---------------------------
1    1            Ford
2    1            BMW
3    1            VW
4    2            Tetris
5    2            Pong
6    3            Foobar Pencil Factory

我想要一个返回类别和第一个(并且只有第一个)项目名称的查询:

category.id category.name item.id item.itemname
-------------------------------------------------
1           Cars          1       Ford
2           Games         4       Tetris
3           Pencils       6       Foobar Pencil Factory

有没有办法我可以得到随机结果,例如:

category.id category.name item.id item.itemname
-------------------------------------------------
1           Cars          3       VW
2           Games         5       Pong
3           Pencils       6       Foobar Pencil Factory

谢谢!

【问题讨论】:

如何定义“第一”?它看起来像 item 中的最低 ID 值? 是的,我的错。首先,我的意思是最低的 ID。 【参考方案1】:

刚刚做了一个快速测试。这似乎有效:

mysql> select * from categories c, items i
    -> where i.categoryid = c.id
    -> group by c.id;
+------+---------+------+------------+----------------+
| id   | name    | id   | categoryid | name           |
+------+---------+------+------------+----------------+
|    1 | Cars    |    1 |          1 | Ford           |
|    2 | Games   |    4 |          2 | Tetris         |
|    3 | Pencils |    6 |          3 | Pencil Factory |
+------+---------+------+------------+----------------+
3 rows in set (0.00 sec)

我认为这将满足您的第一个问题。不确定第二个 - 我认为这需要一个带有 random() 顺序的内部查询或类似的东西!

【讨论】:

随机结果对我来说并不重要,所以这正是我想要的!谢谢【参考方案2】:

Mysql 允许您拥有不包含在分组或聚合中的列,在这种情况下它们有随机值:

    select category.id, category.name, itemid, itemname
    inner join 
      (select item.categoryid, item.id as itemid, item.name as itemname
       from item group by categoryid)
    on category.id = categoryid

或者,至少,

select category.id, category.name, itemid, itemname
inner join 
  (select item.categoryid, min(item.id) as itemid, item.name as itemname
  from items
  group by item.categoryid)
on category.id = categoryid

【讨论】:

我在尝试此方法时遇到错误:“每个派生表都必须有自己的别名”。我想我在某个地方做错了什么。【参考方案3】:

Mysql 确实让包含非聚合列并且不能保证确定性,但根据我的经验,我几乎总是得到第一个值。

所以通常(但不能保证)这会给你第一个

select * 
from categories c, items i
where i.categoryid = c.id
group by c.id;

如果你想得到保证,你需要做类似的事情

select categories.id, categories.name, items.id, items.name
from categories inner join
  items on items.categoryid = categories.id and 
     items.id = (select min(items2.id) from items as items2 where items2.categoryid = category.id)

如果您想要随机答案,则必须稍微更改子查询

 select categories.id, categories.name, items.id, items.name
    from categories inner join
      items on items.categoryid = categories.id and 
         items.id = (select items2.id from items as items2 where items2.categoryid = category.id order by rand() limit 1)

【讨论】:

以上是关于MySQL 查询:限制 JOIN的主要内容,如果未能解决你的问题,请参考以下文章

MySQL Inner Join 有限制吗?

MySql 之 left join 查询结果

MySQL的join

mysql的inner join,left jion,right join,cross join以及on和where的区别

mysql优化总结

这两种 MySQL 查询形式总是等价的吗?分组依据 + 排序依据 + 限制