这是我的问题:即使第二个表没有相应的条目,也可以从2个db表中获取查询结果。
以下是我在SQL中使用的一些示例代码
SELECT DISTINCT apps.id, apps.*, req.status
FROM applications AS apps, requests AS req
WHERE apps.id = {$app_id}
但问题是它不会提取没有request.status值/条目的应用程序,所以问题是:是否可以修改这个简单的查询来为所有应用程序提取结果。*行即使没有相应的requests.status row / entry?
编辑BELLOW:
所以这是我从我得到的反馈中得到的新查询(这很好)
SELECT DISTINCT
apps.*, req.status
FROM
applications AS apps
LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id})
WHERE
apps.id = {$app_id}
BUT:当我在where子句中添加一个新表达式来过滤请求状态时,我得到与隐式查询相同的问题,我没有得到结果(查询如下)
SELECT DISTINCT
apps.*, req.status
FROM
applications AS apps
LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id})
WHERE
apps.id = {$app_id}
AND
(req.status = 2 OR req.status = 5)
另一个编辑
这是要查看的更新代码。 现在的问题是,如果我添加子查询,子查询将拉出所有行,然后将NULL作为状态列的值,但是只要我添加WHERE状态!= 2它就会删除所有条目,不应该这仍然有所有行为null?因为null显然是!= 2。
SELECT DISTINCT
apps . *
FROM
(SELECT
apps . *, req.status
FROM
appstore_app AS apps
LEFT JOIN app_user_request AS req ON (req.uid = 187 AND req.appid = apps.appid)
WHERE
apps.appid > 0 AND apps.company_id = 122) AS apps
WHERE
apps.status != 2
ORDER BY apps.average_user_rating DESC
最终编辑
感谢所有帮助!
这是我的最终查询对我有用:
SELECT
apps.*, req.status
FROM
appstore_app AS apps
LEFT JOIN
app_user_request AS req ON (req.uid = {$user_id} AND req.appid = apps.appid AND (req.status IS NULL OR req.status != 2))
WHERE
apps.appid > 0 AND apps.company_id = {$company_id}
答案 0 :(得分:0)
您的查询使用隐式交叉连接,从两个表中选择数据,而不指定关联两个表的方法。你真正想要的是一个左连接。
SELECT DISTINCT apps.id, apps.*, req.status
FROM applications AS apps
LEFT JOIN requests AS req
ON apps.id = req.apps_id /* Guessing on the relationship here */
WHERE apps.id = {$app_id}
一旦语法正确,请查看此查询是否真的需要DISTINCT
。这可能是昂贵的开销,可以消除。
编辑:添加以下部分以回复编辑过的问题。
在WHERE子句中测试LEFT JOINed列(在您的情况下为req.status
)时,强制该连接的行为就像它是INNER JOIN一样。相反,将这些测试作为连接条件的一部分。
SELECT DISTINCT
apps.*, req.status
FROM
applications AS apps
LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id})
AND (req.status = 2 OR req.status = 5)
WHERE
apps.id = {$app_id}
答案 1 :(得分:0)
SELECT DISTINCT
apps.*, req.status
FROM
applications AS apps
LEFT JOIN requests AS req on req.app_id = apps.id
WHERE
apps.id = {$app_id}
答案 2 :(得分:0)
即使没有相应的requests.status,LEFT JOIN
也会显示所有应用程序。
SELECT DISTINCT apps.id, apps.*, req.status
FROM applications apps
LEFT JOIN requests req ON req.? = applications.?
WHERE apps.id = {$app_id}
您需要添加将两个表链接在一起的列(?
)。
答案 3 :(得分:0)
你需要使用这样的显式LEFT JOIN:
SELECT DISTINCT apps.id, apps.*, req.status
FROM applications AS apps
LEFT JOIN requests AS req ON apps.whatever_field_relates = req.whatever_field_relates
WHERE apps.id = {$app_id}
像FROM table1, table2
一样使用隐式JOINS并不是IMO的好习惯。这使得其他程序员很难在不必参考数据库模式的情况下一目了然地了解JOIN的确切性质。
答案 4 :(得分:0)
SELECT DISTINCT app.*,req.status
from applications apps
left join request as req on req.appid = apps.id
where apps.id ={$app_id}
做一个左连接就可以了,我习惯了TSQL语法,但我相信它可以在Mysql中运行。您需要在两个表格中使用您的应用的ID,才能加入它们。
答案 5 :(得分:0)
O.P。表示:
BUT:当我向where子句添加新表达式以过滤请求状态时,i>得到与隐式查询相同的问题,我没有得到结果(查询如下)
SELECT DISTINCT apps.*, req.status FROM applications apps LEFT JOIN requests req ON req.app_id = apps.id AND req.uid = {$user_id} WHERE apps.id = {$app_id} AND ( req.status = 2 OR req.status = 5 )
问题是where
子句过滤了结果集,因此对req.status
的2或5的测试会抛出req.status
为空的任何内容,因为没有与表匹配的行applications
。
一般的,理论上的(因为除了一个简单的实现之外什么都不会做这样的事情)select
语句的操作顺序是:
from
子句中列出的每个表的完整笛卡尔积。join
条件对其进行过滤,并删除未通过指定测试的行。where
子句中指定的过滤条件,删除未通过指定测试的行。group by
子句中指定的表达式上对结果集进行排序,并将结果集合分组。select
语句列列表中未列出的所有列。order by
子句中指定的列/表达式对此最终结果进行排序。你可以做以下两件事之一:
更改您的查询以测试无效:
where...( req.status is null OR req.status in (2,5) )...
将针对req.status
的测试移至加入条件:
left join requests req on req.app_id = apps.id
and req.uid = {$user_id}
and req.status in (2,5)