1

所以我又来了。我有 2 张桌子:

ci_products:

在此处输入图像描述

ci_prodimages:

http://img832.imageshack.us/img832/8672/kv3b.png

我有一个带有 join 和GROUP_CONCAT.

SELECT *, GROUP_CONCAT(img_url) urls FROM (`ci_products`) 
JOIN `ci_prodimages` ON `ci_prodimages`.`img_pid`=`ci_products`.`prod_id` 
WHERE `prod_cat` = '4' OR `prod_cat` = '8' OR `prod_cat` = '9' OR `prod_cat` = '10'

此 SQL 应返回所有 3 个产品。但它只返回带有prod_cat - 10. 其他一切都在工作,但这个。

还有这个查询:

SELECT *, GROUP_CONCAT(img_url) urls FROM (`ci_products`) 
JOIN `ci_prodimages` ON `ci_prodimages`.`img_pid`=`ci_products`.`prod_id` 
WHERE `prod_cat` = '9'

结果为空结果。

任何帮助表示赞赏。谢谢

4

2 回答 2

1

您正在使用GROUP_CONCATwhich 是一个聚合函数,但不使用 GROUP BY。MySQL 确实允许隐式分组,您可以在其中选择既不在 group by 也不在聚合中的列,但正如您所见,您可能会遇到问题。我也不推荐使用 SELECT *,所以你的查询最好写成:

SELECT  p.prod_id, 
        p.Prod_Name, 
        p.prod_desc, 
        p.prod_nem, 
        p.prod_cat, 
        p.prod_minpric,
        p.prd_minbid,
        p.prod_marks,
        p.prod_added, GROUP_CONCAT(img_url) urls 
FROM    `ci_products` p
        JOIN `ci_prodimages` i
            ON p.`img_pid`= i.`prod_id` 
WHERE   `prod_cat` = '9'
GROUP BY p.prod_id, p.Prod_Name, p.prod_desc, p.prod_nem, p.prod_cat, p.prod_minpric, p.prd_minbid, p.prod_marks, p.prod_added

在 MySQL 中(并且根据 SQL 标准),以下内容也是合法的:

SELECT  p.prod_id, 
        p.Prod_Name, 
        p.prod_desc, 
        p.prod_nem, 
        p.prod_cat, 
        p.prod_minpric,
        p.prd_minbid,
        p.prod_marks,
        p.prod_added, GROUP_CONCAT(img_url) urls 
FROM    `ci_products` p
        JOIN `ci_prodimages` i
            ON p.`img_pid`= i.`prod_id` 
WHERE   `prod_cat` = '9'
GROUP BY p.prod_id;

由于prod_id是表的主键,ci_products因此不必按所有列分组,因为它们在功能上依赖于主键,但是,MySQL 并未严格执行此标准,这可能导致意外行为,因此我仍然建议明确列出您分组的所有列。

下面是我之前写的一个标准解释,用于解释 MySQL 隐式分组是如何工作的,以及我为什么要避免它:


我建议尽可能避免 MySQL 提供的隐式分组,我的意思是在选择列表中包含列,即使它们不包含在聚合函数或 group by 子句中。

想象一下下面的简单表(T):

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Y     |

在 MySQL 中,您可以编写

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1;

这实际上打破了 SQL 标准,但它在 MySQL 中有效,但问题是它是不确定的,结果:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |

不比正确或不正确

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

所以你说的是给我一个不同的值Column1,两个结果集都满足,那么你怎么知道你会得到哪一个?好吧,您不知道,这似乎是一个相当流行的误解,您可以添加和ORDER BY子句来影响结果,例如以下查询:

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1
ORDER BY ID DESC;

将确保您获得以下结果:

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

由于ORDER BY ID DESC, 然而这不是真的(如此处所示)。

MySQL文档状态:

服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。

因此,即使您有这样的订单,直到每组选择一行之后才适用,并且这一行是不确定的。

SQL 标准确实允许选择列表中的列不包含在 GROUP BY 或聚合函数中,但是这些列必须在功能上依赖于 GROUP BY 中的列。例如,示例表中的 ID 是 PRIMARY KEY,所以我们知道它在表中是唯一的,所以下面的查询符合 SQL 标准,在 MySQL 中运行,目前在许多 DBMS 中会失败(在编写 Postgresql 时)是我所知道的最接近正确实施标准的 DBMS):

SELECT  ID, Column1, Column2
FROM    T
GROUP BY ID;

由于每一行的 ID 是唯一的,因此每个 ID 只能有一个值Column1,一个值Column2对于每一行返回的内容没有歧义。

于 2013-08-15T15:51:32.330 回答
0

inner join仅返回两个表中匹配的行:

FROM ci_products p
JOIN ci_prodimages i ON i.img_pid = p.prod_id

改为尝试 a left join,它返回左侧表中的所有条目:

FROM ci_products p
LEFT JOIN ci_prodimages i ON i.img_pid = p.prod_id
于 2013-08-15T15:53:24.050 回答