我正在尝试了解JOIN
和LEFT JOIN
的区别。我观看了几个youtube视频并研究了Google。但是,我无法理解为什么我的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'];
}
答案 0 :(得分:2)
由于sales
和users
都有一个名为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
答案 1 :(得分: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
答案 2 :(得分:1)
关注“试图了解JOIN
和LEFT 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)
答案 3 :(得分:0)
如果您要加入的两个表中都有给定的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)。然后使用该别名,您可以指定从哪个表中选择哪个列。
另外,我建议不要将列命名为“date”,因为它是MySQL的保留字。请参阅:http://dev.mysql.com/doc/refman/5.6/en/reserved-words.html
答案 4 :(得分:0)
引入表别名,以便在引用字段时引用它。您的问题是两个表中都有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