0

这是我的问题:即使第二个表没有相应的条目,也可以从 2 个 db 表中获取查询结果。

这是我在 SQL 中使用的一些示例代码

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

但问题是它不会提取没有 request.status 值/条目的应用程序,所以问题是:是否可以修改这个简单的查询以提取所有 application.* 行的结果,即使有是没有对应的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}

但是:当我在 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 status != 2 它只会删除所有条目,这不应该还有所有为空的行吗?因为 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}
4

6 回答 6

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真的需要这个查询。它可能是可以消除的昂贵的开销。

编辑:添加以下部分以响应已编辑的问题。

当您req.status在 WHERE 子句中测试 LEFT JOINed 列(在您的情况下)时,您强制该连接表现得好像它是一个 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}
于 2012-08-31T18:55:36.647 回答
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}
于 2012-08-31T18:55:46.727 回答
0

LEFT JOIN即使没有相应的 requests.status 存在,A也会显示您的所有应用程序。

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

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

于 2012-08-31T18:56:46.097 回答
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 likeFROM table1, table2不是 IMO 的好习惯。这使得其他程序员很难一目了然地理解 JOIN 的确切性质,而不必参考数据库模式。

于 2012-08-31T18:58:52.600 回答
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,才能加入它们。

于 2012-08-31T19:04:00.463 回答
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子句过滤了结果集,因此您对 areq.status的 2 或 5 的测试会抛出任何req.status为 null 的内容,因为没有行与 table 匹配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)
    
于 2012-08-31T19:52:35.880 回答