【问题标题】:Proper way to join these tables?加入这些表的正确方法?
【发布时间】:2013-07-05 23:03:08
【问题描述】:

我正在尝试了解JOINLEFT JOIN 的区别。我看了几个 youtube 视频并研究了谷歌。但是,我不太明白为什么我的 JOIN 查询不起作用。如果我运行 sql,我会得到 Column 'user_id' in field list is ambiguous

销售表

sales_id   user_id   amount    date         status
3          1         1258.32   2013-07-02   S

用户表

user_id   fname   lname
1         John    Doe

我的代码:

$top = mysqli_query($mysqli, "SELECT user_id, fname, lname, SUM(amount) as total 
FROM sales
LEFT JOIN users ON
user_id.sales = user_id.users
WHERE status = 'S' AND MONTH(date) = MONTH(CURDATE()) AND YEAR(date) = YEAR(CURDATE()) GROUP BY user_id ORDER BY total DESC LIMIT 5");

     while($row = mysqli_fetch_assoc($top)) {
           $topamount[]     = $row['total'];
           $topfnameuser[]  = $row['fname'];
           $toplnameuser[]  = $row['lname'];
     }

【问题讨论】:

    标签: php join mysqli


    【解决方案1】:

    由于salesusers 都有一个名为user_id 的列,因此您必须在SELECT 列表中具体说明您想要了解的内容:

    SELECT sales.user_id as user_id, fname, lname, SUM(amount) as total 
    FROM sales
    LEFT JOIN users
    ON sales.user_id = users.user_id
    WHERE status = 'S' AND MONTH(date) = MONTH(CURDATE()) AND YEAR(date) = YEAR(CURDATE()) 
    GROUP BY user_id
    ORDER BY total DESC
    LIMIT 5
    

    您还在ON 子句中将表名和列名倒置。是table.column,不是column.table

    【讨论】:

    • 再次感谢!!你摇滚!
    【解决方案2】:

    我认为您对使用 LEFT JOIN 有误解, 尝试这个.. 我已经创建了你想要的表,如果我使用你的查询并解决它,我会出错,所以查询是这样的

    SELECT fname,lname, SUM(amount) AS total
      FROM users LEFT JOIN sales
      ON users.user_id = sales.user_id
        WHERE sales.status = 'S' AND MONTH(sales.date) = MONTH(CURDATE()) AND YEAR(sales.date) = YEAR(CURDATE()) GROUP BY users.user_id
    ORDER BY total DESC LIMIT 5
    

    【讨论】:

      【解决方案3】:

      关注“试图了解JOINLEFT JOIN 的区别”部分,当您想要查看一个表中的所有行时,外连接非常有用,即使是那些在另一个相关表中没有对应行的行。

      这是一个使用学生和考试成绩的简单示例。

      create table students (student_id serial primary key, student_name text);
      create table tests (test_id serial primary key, test_name text, test_date date);
      create table grades (
          student_id int,
          test_id int,
          grade char,
          primary key (student_id, test_id),
          foreign key (student_id) references students (student_id),
          foreign key (test_id) references tests (test_id));
      
      insert into students (student_name) values ('joe');
      insert into students (student_name) values ('amber');
      insert into students (student_name) values ('steve');
      
      insert into tests (test_name, test_date) values ('test 1', '2013-01-20');
      insert into tests (test_name, test_date) values ('test 2', '2013-02-10');
      
      insert into grades (student_id, test_id, grade) values (1, 1, 'A');
      insert into grades (student_id, test_id, grade) values (1, 2, 'B');
      insert into grades (student_id, test_id, grade) values (2, 1, 'B');
      insert into grades (student_id, test_id, grade) values (2, 2, 'A');
      

      以下查询将返回学生及其成绩的列表,其中包括一行标识尚无任何成绩的学生(在本例中为 Steve):

      select s.student_name, t.test_name, t.test_date, g.grade
      from students as s
      left join grades as g on s.student_id = g.student_id
      left join tests as t on g.test_id = t.test_id;
      
      student_name | test_name | test_date  | grade 
      --------------+-----------+------------+-------
      joe          | test 1    | 2013-01-20 | A
      joe          | test 2    | 2013-02-10 | B
      amber        | test 1    | 2013-01-20 | B
      amber        | test 1    | 2013-01-20 | A
      steve        |           |            | 
      (5 rows)
      

      使用外连接的一种非常有用的方法是,当您希望在相关表中查看行而不匹配行时。您也可以使用子查询来执行此操作,但使用外连接也不错:

      select s.student_name                                   
      from students as s
      left join grades as g on s.student_id = g.student_id
      where g.student_id is null;
      student_name 
      --------------
      steve
      (1 row)
      

      ...在功能上等同于:

      select student_name from students where student_id not in (select student_id from grades); 
      student_name 
      --------------
      steve
      (1 row)
      

      【讨论】:

        【解决方案4】:

        引入表别名,以便在引用字段时引用它。您的问题是您在两个表中都有 user_id 并且您尚未定义从哪个表读取 user_id。

        "SELECT s.user_id, u.fname, u.lname, SUM(s.amount) as total 
        FROM sales AS s
        LEFT JOIN users AS u ON
        s.user_id = u.user_id
        

        【讨论】:

          【解决方案5】:

          当给定的 id 在您要加入的两个表中时,您使用 JOIN

          当给定的 id 在一个表中并且可能在第二个表中时,您使用LEFT JOIN

          在您的情况下,您应该从用户中选择并离开加入销售

          SELECT u.user_id, u.fname, u.lname, SUM(s.amount) as total 
          FROM users u LEFT JOIN sales s ON s.user_id = u.user_id
          WHERE s.status = 'S' AND MONTH(s.date) = MONTH(CURDATE()) AND YEAR(s.date) = YEAR(CURDATE())
          GROUP BY u.user_id
          ORDER BY total DESC LIMIT 5
          

          注意表命名中的别名(用户 u)。然后使用该别名,您可以指定要从哪个表中选择哪一列。

          另外,我建议不要将列命名为“日期”,因为它是 MySQL 的保留字。见:http://dev.mysql.com/doc/refman/5.6/en/reserved-words.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-01-10
            • 2014-05-05
            • 1970-01-01
            • 2021-06-29
            • 1970-01-01
            • 1970-01-01
            • 2016-02-24
            • 2014-12-01
            相关资源
            最近更新 更多