2012-08-31 16 views
0

这是我的问题:即使第二个表没有对应条目,也从2个数据库表获取查询结果。即使在第二个表没有对应条目的情况下也能从2个数据库表获得查询结果

这里是我在SQL

SELECT DISTINCT apps.id, apps.*, req.status 
FROM applications AS apps, requests AS req 
WHERE apps.id = {$app_id} 

使用一些示例代码但问题是,它会拉不上来没有一个request.status值/进入应用程序,所以问题是:会可以修改这个简单的查询来为所有应用程序提取结果*行,即使没有相应的requests.status行/条目时也是如此。

编辑贝洛:

所以这里是我从我得到的反馈新的查询(这工作正常)

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} 

但是:当我添加一个新的表达到哪里子句来过滤请求状态,我得到与隐式查询相同的问题,我没有得到结果(查询是波纹管)

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) 

ANOTHER编辑

这里更新代码来看看。 现在的问题是,如果我添加一个子查询,子查询将拉起所有的行,然后作为状态列的值为NULL,但只要我添加一个WHERE状态!= 2它只是删除所有条目,这不应该仍然有所有行的空?因为空显然是!= 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

OP说:

但是:当我添加一个新的表达式WHERE子句来过滤请求状态,我>得到了同样的问题与隐式查询,我没有得到结果(查询是波纹管)

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子句对结果进行过滤设置,让你的的2 req.status或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) 
    
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一样。相反,使这些测试成为连接条件的一部分。即使没有相应的requests.status存在

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} 
+0

是的,我也想到了,但问题是,我得到的结果为req.status为NULL的行。 – mxaddict

+0

由于您的'application'表中的行在您的'requests'表中没有匹配的行,因此您实际上没有状态码,因此为'null'值。你需要用'coalesce'指定一些默认值:'coalesce(req.status,-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} 
0

一个LEFT JOIN将显示所有的应用程序。

SELECT DISTINCT apps.id, apps.*, req.status 
FROM applications apps 
LEFT JOIN requests req ON req.? = applications.? 
WHERE apps.id = {$app_id} 

您需要添加将两个表链接在一起的列(?)。

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} 

使用隐含JOINS像FROM table1, table2是不是好的做法IMO。这让其他程序员很难理解JOIN的确切性质,而无需引用数据库模式。

+0

好的,谢谢你的回复,这很好,但我碰到一个问题,当我在where子句中添加“AND req.status!= 2”时,在请求表中没有值时我没有得到任何结果。 – mxaddict

+0

这是因为您正在过滤请求表中的项目。这实质上将失去进行LEFT JOIN的目的。对于这样的查询,你可能会有一个普通的INNER JOIN,因为你永远不会在应用程序中返回不匹配的记录。 –

+0

你认为它会工作,如果我创建一个子查询?如下所示: SELECT * FROM(SELECT DISTINCT apps。*,req.status FROM applications AS apps LEFT JOIN requests AS req ON(apps.id = req.app_id AND req.user_id = {$ user_id})WHERE apps.user_id = {$ user_id})AS应用程序WHERE状态= 2; – mxaddict

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,才能加入它们。

相关问题