0

これが私の問題です。2番目のテーブルに対応するエントリがない場合でも、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 行/エントリはありませんか?

以下を編集:

だからここに私が得たフィードバックからの私の新しいクエリがあります(これはうまくいきます)

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 status != 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}
4

6 に答える 6

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

クエリは暗黙的なクロス結合を使用しており、2 つのテーブルを関連付ける方法を指定せずに 2 つのテーブルからデータを選択しています。あなたが本当に欲しいのは左結合です。

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}
于 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 JOINrequests.status が存在しない場合でも、すべてのアプリケーションが表示されます。

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 like を使用するFROM table1, table2ことは、IMO の良い習慣ではありません。データベース スキーマを参照しなくても、他のプログラマが JOIN の正確な性質を一目で理解することは困難です。

于 2012-08-31T18:58:52.600 に答える
0

OP は次のように述べています。

BUT:要求ステータスをフィルタリングするために 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 または 5 の a のテストでは、 table に一致する行がないため、nullreq.statusであるすべてのものをスローします。req.statusapplications

selectステートメントの操作の一般的で理論的な順序は次のとおりです。

  • from句にリストされている各テーブルの完全デカルト積を生成します。
  • join指定された基準を適用し、指定されたテストに合格しない行を除外することで、それをフィルタリングします。
  • 句で指定されたフィルター基準を適用し、where指定されたテストに合格しない行を削除します。
  • group by句で指定された式で結果セットを並べ替え、結果セットをグループに分割します。
  • そのような各グループを単一の行に折りたたみ、指定されたすべての集約関数の値を計算します。
  • selectステートメント列リストにリストされていない結果セットからすべての列を削除します。
  • order by句で指定された列/式によって、この最終結果セットを並べ替えます。

次の 2 つのいずれかを行うことができます。

  • nullity をテストするようにクエリを変更します。

    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 に答える