sql >> データベース >  >> RDS >> Mysql

LEFT JOINは、左側のテーブルからすべてのレコードを返すわけではありません

    問題は、結合に一致しない部門サービスもフィルタリングするwhere条件を使用して結合テーブルでフィルタリングし、結合でフィルタリングを移動し、d where句内:

    SELECT d.mt_code,
       d.dep_name,
       d.service_name,
       COUNT(t.id)
    FROM DepartmentService AS d
    LEFT JOIN tbl_outgoing AS t 
      ON d.mt_code = t.depCode 
        AND t.smsc = "mobitelMT"
        AND t.sendDate BETWEEN '2014-07-01' AND '2014-07-02'
    WHERE d.service_type = 'MT'
    GROUP BY d.mt_code
    

    これが発生する理由を説明するために、これを使用するデータセットとして、クエリとクエリで何が発生するかを説明します。

    states
     ____ _________ 
    | id | state   |
    |  1 | Germany |
    |  2 | Italy   |
    |  3 | Sweden  |
    |____|_________|
    
    cities
    
     ____ ________ ___________ ____________
    | id | city   | state_fk  | population |
    |  1 | Berlin |        1  |         10 |
    |  2 | Milan  |        2  |          5 |
    |____|________|___________|____________|
    

    まず、クエリを実行します。

    SELECT s.id, s.state, c.population, c.city
    FROM states s
    LEFT JOIN cities c
    ON c.state_fk = s.id
    WHERE c.population < 10
    

    したがって、段階的に進むのではなく、3つの州を選択し、最後に次の都市に参加します。

     ____ _________ ____________ ________
    | id | state   | population | city   |
    |  1 | Germany |         10 | Berlin |
    |  2 | Italy   |          5 | Milan  |
    |  3 | Sweden  |       NULL | NULL   |
    |____|_________|____________|________|
    

    WHERE c.population < 10を使用して母集団をフィルタリングします 、この時点であなたの左はこれです:

     ____ _________ ____________ ________
    | id | state   | population | city   |
    |  2 | Italy   |          5 | Milan  |
    |____|_________|____________|________|
    

    ベルリンの人口が10人だったため、ドイツを失いましたしかし、スウェーデンも失いました NULLがあった場合、nullを保持したい場合は、クエリで指定する必要があります:

    WHERE (c.population < 10 OR IS NULL c.population)
    

    どちらが返されますか:

     ____ _________ ____________ ________
    | id | state   | population | city   |
    |  2 | Italy   |          5 | Milan  |
    |  3 | Sweden  |       NULL | NULL   |
    |____|_________|____________|________|
    

    今私の質問:

    SELECT s.id, s.state, c.population, c.city
    FROM states s
    LEFT JOIN cities c
    ON c.state_fk = s.id
      AND c.population < 10
    

    2つを結合する前に、テーブルの都市をフィルタリングします(AND c.population < 10を使用) ONの後の状態 )、残っているのは:

     ____ ________ ___________ ____________
    | id | city   | state_fk  | population |
    |  2 | Milan  |        2  |          5 |
    |____|________|___________|____________|
    

    ミラノは人口が10人未満の唯一の都市であるため、現在 2つのテーブルを結合できます:

     ____ _________ ____________ ________
    | id | state   | population | city   |
    |  1 | Germany |       NULL | NULL   |
    |  2 | Italy   |          5 | Milan  |
    |  3 | Sweden  |       NULL | NULL   |
    |____|_________|____________|________|
    

    ご覧のとおり、フィルタリング条件がのみ適用されたため、左側のテーブルのデータはそのままです。 都市のテーブルに。

    結果セットは、達成したい内容に応じて変わります。たとえば、ベルリンの人口が10未満であるためにドイツをフィルタリングし、スウェーデンを維持する場合は、最初のアプローチを使用してIS NULLを追加する必要があります。 条件を維持したい場合は、2番目のアプローチを使用して、左側の結合の右側にあるテーブルを事前にフィルタリングする必要があります。




    1. Oracle11g-PL/SQLカーソルの実行

    2. ResultSetのOracleJDBCパフォーマンス

    3. 1つのクエリ内でSETとSELECT?

    4. SQL Server 2008 で偶数行または奇数行のみを表示する方法は?