选择*从多个表。的MySQL


76

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
嗯,您有5个匹配的行,因为您有几行具有相同的Drinks_id。您会期望发生什么?您希望保留哪张照片?
乔恩·斯基特

Answers:


108

您在这里所做的称为a JOIN(尽管您是隐式执行的,因为您是从多个表中选择的)。这意味着,如果您未在WHERE子句中放置任何条件,则您将拥有这些表的所有组合。仅根据您的条件,您才可以将联接限制为饮料ID匹配的行。

但是,如果有X张包含此特定Drinks_id的照片,则每种饮料的结果中仍会有X多个行。你的陈述不限制哪个你想有张相片!

如果每杯饮料只需要一行,则必须告诉SQL如果有多个具有特定Drinks_id的行要做什么。为此,您需要分组和聚合函数。您告诉SQL您要将哪些条目分组(例如,所有相等的Drinks_ids),然后在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聚合函数。


是的,我想要每种饮料的名称,价格和图像数组。
NestedWeb

3
您使用哪种语言编写程序来执行这些查询?因为MySQL不支持将数组作为字段类型。您必须使用来完成一些字符串技巧,GROUP_CONCAT然后再次拆分。通常在关系数据库中不会这样做。您应该在程序中而不是在SQL中进行分组(检测重复的ID并在程序中构建这些数组)。
leemes 2012年


@NestedWeb如果要使用所有图像,最好不要使用GROUP BYand (更好)GROUP_CONTACT,而是继续使用,但按进行排序drinks.id。这样,您就可以遍历结果集并将图像收集到客户端的数组中。
bhovhannes 2012年

它等效于INNER JOIN。
斯瓦沃米尔Lenart

3

您将在此处获得名称和价格的重复值。而且ids在Drinks_photos表中是重复的。您无法避免它们。您究竟想要什么输出?


2

为了消除重复项,您可以按分组drinks.id。但是那样的话,每张照片只会得到一张照片drinks.id(您将获得的照片取决于数据库内部的实现)。

尽管没有记录,但是对于MySQL,您将获得最低的照片id(以我的经验,我从未见过其他行为)。

SELECT name, price, photo 
FROM drinks, drinks_photos 
WHERE drinks.id = drinks_id
GROUP BY drinks.id

1
您最好按ID分组。始终按唯一字段分组以获取源表的不同行。在您的情况下,如果两种饮料的名称相同(但表中的行不同),您也将它们分组在一起。
leemes 2012年

谢谢leemes,我没注意到有唯一的id字段。我已经编辑了答案。当然使用id更好。@ypercube,您是否真的认为您的评论添加了通常发布的内容?
bhovhannes 2012年

@bhovhannes:不,你是对的,对不起。尖刻的注释不会添加任何有用的内容。正确答案会更好-尽管我仍然不同意这种用法GROUP BY(不是SQL标准),但没有解释其工作原理以及photo每种饮料如何返回半随机值。(在“第一”“你会得到的第一张照片”的短语是错误的)。
ypercubeᵀᴹ

@ypercube,是的,使用GROUP BY筛选行(例如在这种情况下)不是SQL标准。但这绝对适用于MySQL,速度很快,并且返回的photoID最低。我从未见过MySQL中的另一种行为(尽管没有记录)。我已在我的帖子中添加了便条
bhovhannes 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.