0
SELECT * FROM (
    SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
    FROM         current_tbl a
    INNER JOIN   import_tbl  b 
                 ON ( a.user_id = b.user_id )
    UNION
    SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
    FROM         current_tbl a
    INNER JOIN   import_tbl  b 
                 ON (   lower(a.f_name)=lower(b.f_name) 
                    AND lower(a.l_name)=lower(b.l_name) ) 
) foo
--
UNION
--
SELECT a.user_id , a.f_name , a.l_name , '' , '' , '' 
FROM   current_tbl a
WHERE  a.user_id NOT IN (
   select user_id from(
      SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
      FROM         current_tbl a
      INNER JOIN   import_tbl  b 
                   ON ( a.user_id = b.user_id )
      UNION
      SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
      FROM         current_tbl a
      INNER JOIN   import_tbl  b 
                   ON (   lower(a.f_name)=lower(b.f_name) 
                      AND lower(a.l_name)=lower(b.l_name) ) 
   ) bar
)
ORDER BY user_id

テーブル人口の例:

current_tbl:

-------------------------------
user_id  |  f_name  |  l_name
---------+----------+----------
  A1     |  Adam    |  Acorn
  A2     |  Beth    |  Berry
  A3     |  Calv    |  Chard
         |          |

import_tbl:

-------------------------------
user_id  |  f_name  |  l_name
---------+----------+----------
  A1     |  Adam    |  Acorn
  A2     |  Beth    |  Butcher  <- last_name different
         |          |

期待される出力:

-----------------------------------------------------------------------
user_id1  |  f_name1  |  l_name1  |  user_id2  |  f_name2  |  l_name2
----------+-----------+-----------+------------+-----------+-----------
   A1     |  Adam     |  Acorn    |     A1     |  Adam     |  Acorn       
   A2     |  Beth     |  Berry    |     A2     |  Beth     |  Butcher
   A3     |  Calv     |  Chard    |            |           |           

このメソッドを実行すると、行が次のようになる条件が取り除かれます。

   A2     |  Beth     |  Berry    |     A2     |  Beth     |  Butcher

しかし、それはA3行を保持します


これが理にかなっており、過度に単純化していないことを願っています。これは私の他の質問からの続きの質問です。これらの一連の改善により、クエリは最大 32000 ミリ秒から現在の最大 1200 ミリ秒に低下しました。これはかなりの改善です。

サブクエリともちろん通常のインデックスの最適化を使用UNION ALLして最適化できると思いますが、最適な SQL 最適化を探しています。参考までに、この特定のケースは PostgreSQL 用です。

4

1 に答える 1

1

これはほとんど同じで、はるかに小さく、私にとってはより理にかなっているように思えます。私の最初の本能は、より速く実行する必要があるということですが、最高ではないかもしれません:)

SELECT       a.user_id, a.f_name, a.l_name, 
             COALESCE(b.user_id, ''), COALESCE(b.f_name, ''), COALESCE(b.l_name, '')
FROM         current_tbl a
LEFT OUTER JOIN import_tbl  b ON
   ( a.user_id = b.user_id ) OR
   ( lower(a.f_name)=lower(b.f_name) 
     AND lower(a.l_name)=lower(b.l_name) ) 

編集:元の質問で行った以前の変更を元に戻すことをお勧めします。

于 2011-02-16T23:23:42.090 に答える