显示多对多查询的多个值

时间:2015-05-05 13:21:55

标签: mysql sql

我有三张桌子:

  1. 用户
  2. 产品
  3. 用户选择的产品
  4. 用户可以选择多种产品。

    我想编写一个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会有多个结果。即用户可能选择多个产品。因此,查询需要返回用户可能选择的多个产品的所有结果。

2 个答案:

答案 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