我有三张桌子:
用户可以选择多种产品。
我想编写一个SQL查询来查找所有用户,并列出他们选择的所有产品。
这是我目前的查询:
SELECT
u.user_id,CONCAT(u.firstName,' ',u.lastName)as name, u.email,
(SELECT
p.product_id
FROM
user_selected_products p
WHERE
p.user_id= u.user_id
)as productsSelected
FROM
users u;
以下是我的表格:
CREATE TABLE users(
user_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
firstName VARCHAR(30) NOT NULL,
lastName VARCHAR(40) NOT NULL,
email VARCHAR (80) NOT NULL
);
CREATE TABLE products (
product_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
product_name VARCHAR(150) NULL,
PRIMARY KEY (product_id),
INDEX productName( product_name )
);
CREATE TABLE user_selected_products (
user_id MEDIUMINT UNSIGNED NOT NULL ,
product_id MEDIUMINT UNSIGNED NOT NULL ,
INDEX selectedProductName(user_id,product_id )
);
我收到以下错误:
:子查询返回多行
子查询无效,因为我试图返回多个值。编写此查询的正确方法是什么?
更新
我希望看到用户选择的所有产品
表格user_selected_products
会有多个结果。即用户可能选择多个产品。因此,查询需要返回用户可能选择的多个产品的所有结果。
答案 0 :(得分:1)
您不需要子查询,可以使用left join
,如下所示
SELECT
u.user_id,CONCAT(u.firstName,' ',u.lastName)as name, u.email,
p.product_id as productsSelected
FROM users u
LEFT JOIN user_selected_products p on p.user_id= u.user_id;
如果你想看到一行中的所有praodutcs尝试使用group_concat
SELECT
u.user_id,CONCAT(u.firstName,' ',u.lastName)as name, u.email,
group_concat(p.product_id) as productsSelected
FROM users u
LEFT JOIN user_selected_products p on p.user_id= u.user_id
GROUP BY u.user_id;
答案 1 :(得分:0)
首先,问题;你得到这个错误的原因是非常自我解释,你有一个子查询返回多个值,但是试图将它作为结果表的一个单元格,这是不允许的。单元格不能有多个值。
该解决方案不需要子查询。您的user_selected_products表包含您需要的所有内容。如果您想查看用户和产品信息,可以使用联接,如下所示:
SELECT u.user_id, CONCAT(u.firstName, ' ', u.lastName) AS name, u.email, p.product_id
FROM users u
JOIN user_selected_products p
ON p.user_id = u.user_id
这将为每个用户/产品组合返回多行。如果您想在同一单元格中查看所有product_ids,可以使用GROUP_CONCAT()
函数将逗号分隔开来。你只需要按user_id对它们进行分组,如下所示:
SELECT u.user_id, CONCAT(u.firstName, ' ', u.lastName) AS name, u.email,
GROUP_CONCAT(p.product_id) AS selectedProducts
FROM users u
JOIN user_selected_products p ON p.user_id = u.user_id
GROUP BY u.user_id;
修改强>
以下是一个简短的SQL Fiddle示例,演示了GROUP_CONCAT
的工作原理。如果这不是您希望显示数据的方式,则可以通过多种方式更改连接项的分隔符,并可以按照自己的方式进行设计。
此外,如果您想为每个用户查看一行,无论他们是否有任何选定的产品,您都可以对用户表执行OUTER JOIN
。