我有一个包含两个类似于:
的表的数据库table1
------
Id : long, auto increment
Title : string(50)
ParentId : long
table2
------
Id : long, auto increment
FirstName : string(20)
LastName : string(30)
Zip : string(5)
table2
与table1
有一对多的关系,其中很多都包含零。
我也有以下查询(工作正常,所以忽略拼写错误,这是一个例子):
SELECT t1.Id AS tid, t1.Title, t2.Id AS oid, t2.FirstName, t2.LastName
FROM table t1
INNER JOIN table2 t2 ON t1.ParentId = t2.Id
WHERE t2.Id IN
(SELECT Id FROM table2
WHERE Zip IN ('zip1', 'zip2', 'etc'))
ORDER BY t2.Id DESC
查询会查找table1
中属于table2
中某人的所有项目,其中该人员位于列出的邮政编码之一。
我现在遇到的问题是:我想在列出的邮政编码中显示所有用户(其商品,如果可用),而不仅仅是带有商品的用户。
所以,我想知道,我应该做更多简单的事情,例如:
SELECT Id AS oid, FirstName, LastName FROM table2 WHERE Zip in ('zip1', 'zip2', 'etc')
foreach(result) {
SELECT Id AS tid, Title FROM table2 WHERE ParentId = oid
}
或者我应该提出更详细的单一SQL语句?如果是这样,我能得到一些帮助吗?谢谢!
答案 0 :(得分:2)
如果我理解正确,将INNER JOIN更改为RIGHT JOIN应该返回所有用户,无论他们是否有项目,对于那些没有项目列,项目列将为空。
答案 1 :(得分:2)
查看右连接和分组依据。这很可能会让你得到你想要的查询。
答案 2 :(得分:1)
我同意(并且已经投票)@Lee D和@Bueller。但是,我一般主张LEFT OUTER JOINS,因为我发现更容易概念化它们正在发生什么,特别是当你加入三个或更多表时。考虑一下:
从最终结果集中您想知道的内容开始:
FROM table2 t2
然后添加“可选”数据。
FROM table2 t2
left outer join table1 t1
on t1.ParentId = t2.Id
是否找到匹配项,将始终显示从table2中选择的任何内容。
答案 3 :(得分:1)
一般情况下,如果(且仅限于)
,您应该更喜欢“多种查询”方法在这种情况下,我怀疑,这两个条件可能不适用。
答案 4 :(得分:0)
您应该提出更精细的单个SQL语句,然后使用您喜欢的编程语言处理结果。
答案 5 :(得分:0)
如果我理解正确,我认为你正在寻找类似的东西
SELECT t1.Id AS tid, t1.Title, t2.Id AS oid, t2.FirstName, t2.LastName
FROM table t1
RIGHT OUTER JOIN table2 t2 ON t1.ParentId = t2.Id AND Zip IN ('zip1', 'zip2', 'etc'))
ORDER BY t2.Id DESC
你的JOIN可以有多个条件,RIGHT OUTER会给你table2中的所有行,即使它们在table1中不匹配
答案 6 :(得分:0)
您所描述的内容称为N + 1 query
。您有1个初始查询返回N个结果,然后1个查询每个N个结果。如果N很小,性能差异可能不明显 - 但随着N的增长,性能会越来越大。