SELECT * FROM 多个表。 MySQL
Posted
技术标签:
【中文标题】SELECT * FROM 多个表。 MySQL【英文标题】:SELECT * FROM multiple tables. MySQL 【发布时间】:2012-10-05 02:22:50 【问题描述】:SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_id
产生 5 行(5 个数组),photo
是一行中唯一的唯一字段。 name, price
重复(这里, fanta-
name, price
重复 3 次。)我如何摆脱这些重复?
编辑:我想要name, price
和所有photo
用于每种饮料。
id name price
1. fanta 5
2. dew 4
id photo drinks_id
1. ./images/fanta-1.jpg 1
2. ./images/fanta-2.jpg 1
3. ./images/fanta-3.jpg 1
4. ./images/dew-1.jpg 2
5. ./images/dew-2.jpg 2
【问题讨论】:
你有 5 个匹配的行,因为你有几行具有相同的饮料 ID。你期望会发生什么?您希望保留哪张照片? 【参考方案1】:您将在此处获得重复的名称和价格值。而且 id 在drinks_photos 表中是重复的。你无法避免它们。还有你想要的输出到底是什么?
【讨论】:
【参考方案2】:您在此处执行的操作称为JOIN
(尽管您隐含地执行此操作,因为您从多个表中进行选择)。这意味着,如果您没有在 WHERE 子句中添加任何条件,那么您将拥有这些表的所有组合。只有在您的条件下,您才能将您的加入限制在饮料 id 匹配的那些行中。
但是,如果有 X 张带有此特定饮料 ID 的照片,则每种饮料的结果中仍有 X 多行。您的声明并未限制您想要拥有哪些张照片!
如果您只希望每杯饮料有一行,则必须告诉 SQL 如果有多行具有特定的 Drinks_id,您要做什么。为此,您需要分组和aggregate function。您告诉 SQL 您想要将哪些条目组合在一起(例如所有相等的饮料 ID),并且在 SELECT 中,您必须告诉每个分组结果行的哪些不同条目应该被采用。对于数字,这可以是平均值、最小值、最大值(仅举几例)。
在您的情况下,如果您只想要一排,我看不出查询照片以获取饮料的意义。您可能认为您可以在每杯饮料的结果中包含一个照片数组,但 SQL 无法做到这一点。如果您只想要任何张照片并且您不在乎会得到哪张照片,只需按drinks_id 分组(以便每杯饮品仅获得一行):
SELECT name, price, photo
FROM drinks, drinks_photos
WHERE drinks.id = drinks_id
GROUP BY drinks_id
name price photo
fanta 5 ./images/fanta-1.jpg
dew 4 ./images/dew-1.jpg
在 mysql 中,我们也有 GROUP_CONCAT,如果您希望将文件名连接到一个字符串:
SELECT name, price, GROUP_CONCAT(photo, ',')
FROM drinks, drinks_photos
WHERE drinks.id = drinks_id
GROUP BY drinks_id
name price photo
fanta 5 ./images/fanta-1.jpg,./images/fanta-2.jpg,./images/fanta-3.jpg
dew 4 ./images/dew-1.jpg,./images/dew-2.jpg
但是,如果您在字段值中包含,
,这可能会变得很危险,因为您很可能希望在客户端再次拆分它。它也不是标准的 SQL 聚合函数。
【讨论】:
是的,我想要每种饮料的名称、价格和一系列图片。 您使用哪种语言编写程序来执行这些查询?因为 MySQL 不支持将数组作为字段类型。你必须做一些字符串技巧,比如GROUP_CONCAT
,然后再次拆分它。在关系数据库中通常不会这样做。您应该在程序中进行分组,而不是在 SQL 中(检测重复的 ID 并在程序中构建这些数组)。
@NestedWeb 请也看看***.com/questions/9024248/…
@NestedWeb 如果您想要所有图像,最好(更快)不使用GROUP BY
和GROUP_CONTACT
,但继续按drinks.id
订购。这样你就可以循环遍历结果集并将图像收集到客户端的数组中。
相当于INNER JOIN。【参考方案3】:
为了消除重复,您可以按drinks.id
分组。但这样一来,每个drinks.id
只会获得一张照片(您将获得哪张照片取决于数据库内部实现)。
虽然没有记录,但如果是 MySQL,您将获得id
最低的照片(根据我的经验,我从未见过其他行为)。
SELECT name, price, photo
FROM drinks, drinks_photos
WHERE drinks.id = drinks_id
GROUP BY drinks.id
【讨论】:
你最好按 id 分组。始终按您的唯一字段分组以获得源表的不同行。在您的情况下,如果两种饮料具有相同的名称(但在表中是不同的行),您也可以将它们组合在一起。 谢谢 leemes,我没有注意到有唯一的 id 字段。我已经编辑了我的答案。当然使用 id 更好。 @ypercube,您真的认为您的评论添加了一些通常可以发布的内容吗? @bhovhannes:不,你是对的,对不起。 Snarky cmets 不会添加任何有用的东西。更正的答案更好 - 尽管我仍然不同意GROUP BY
的这种用法(这不是 SQL 标准),但没有解释它为什么起作用以及它将如何为每种饮料返回一个半随机的 photo
。 (“you'll get the first photo” 短语中的 “first” 是错误的)。
@ypercube,是的,使用 GROUP BY 过滤行(例如在这种情况下)不是 SQL 标准。但这绝对适用于 MySQL,速度很快,并且它返回具有最低 id 的photo
。我从未在 MySQL 中看到过其他行为(尽管没有记录)。我在帖子中添加了注释以上是关于SELECT * FROM 多个表。 MySQL的主要内容,如果未能解决你的问题,请参考以下文章
select * from 后有多个表的使用方法(已知一个表的结构为xxx 怎样通过select语句把他变成以下结构)