2016-10-09 3 views
2

他のテーブルのエントリに基づいて結果を並べ替える方法私は私のスキーマ内の2つのテーブルをしました

+----+------+------+------+ 
| id | col1 | col2 | col3 | 
+----+------+------+------+ 
| 1 | abc | NULL | abc | 
| 2 | abc | NULL | NULL | 
| 3 | NULL | abc | abc | 
+----+------+------+------+ 

表B

+------+------+------+ 
| col1 | col2 | col3 | 
+------+------+------+ 
| NULL | abc | abc | 
| abc | NULL | abc | 
| abc | abc | abc | 
+------+------+------+ 

私はすべて選択したいですテーブルAに記録し、テーブル2に同じエントリがある場合はそれらを並べ替える。

この場合、私の答えは

+----+------+------+------+ 
| id | col1 | col2 | col3 | 
+----+------+------+------+ 
| 1 | abc | NULL | abc | 
| 3 | NULL | abc | abc | 
| 2 | abc | NULL | NULL | 
+----+------+------+------+ 

すべてのヘルプや概念は、このような

+0

テーブルBに複数のレコードがあるとどうなりますか? –

+0

table2と一致する行は、結果の回答の先頭になければなりません。 –

+0

これは本当に私の質問に答えるものではないので、私は再度尋ねると思います。表Bに複数のレコードがある場合はどうなりますか? –

答えて

1

何かが動作するはずいただければ幸いです。

SELECT id, col1, col2, col3 
FROM (
    SELECT id, col1, col2, col3, matches, 
      @seq := IF(@id = id, @seq + 1, 
        IF(@id := id, 1, 1)) AS seq 
    FROM (
     SELECT t1.id, t1.col1, t1.col2, t1.col3, 
      IF(t2.col1 IS NULL, 0, 1) + IF(t2.col2 IS NULL, 0, 1) + 
      IF(t2.col3 IS NULL, 0, 1) AS matches 
     FROM tableA AS t1 
     LEFT JOIN tableB AS t2 
     ON COALESCE(t1.col1,0) = COALESCE(t2.col1,0) OR 
      COALESCE(t1.col2,0) = COALESCE(t2.col2,0) OR 
      COALESCE(t1.col3,0) = COALESCE(t2.col3,0)) AS t 
    CROSS JOIN (SELECT @seq := 0, @id :=0) AS vars   
    ORDER BY id, matches DESC ) AS x 
WHERE x.seq = 1 
ORDER BY x.matches DESC, x.id 

すべて取得するようにクエリは、ON句でOR事業者とLEFT JOIN操作を使用していますtableAの各レコードの可能なマッチングは、各レコードがtableBである。変数はidあたりtableAという最も一致するレコードを得るために使用されます。結果は、各tableAレコードの一致数で並べ替えられます。

Demo here

注:クエリがcol1col2col3は値0を取ることはありませんことを前提としています。

+0

テーブルAの各行のテーブルbと一致する行数を回答の新しい列としてもいいですか?その結果、テーブルbと一致しなかった行は0とカウントされます。 –

+0

@SamuelRobertはい、私のクエリはこれに 'matches'フィールドを使います。 'SELECT'節に追加するだけです。 –

+0

すばらしいお礼!!! –

関連する問題