0
---------------------------------
| table_one.col_a| table_one.fk |
---------------------------------
| A              | 4            |
---------------------------------
| B              | 4            |
---------------------------------
| C              | 4            |
---------------------------------

---------------------------------
| table_two.col_b|table_two.fk  |
---------------------------------
| E              | 4            |
---------------------------------
| F              | 4            |
---------------------------------
| G              | 4            |
---------------------------------
| H              | 4            |
---------------------------------

fk が共通の外部キーである場合、このようなものを出力するクエリを探しています

 A_E
 B_F
 C_G
  _H
4

2 に答える 2

1

カウンタ フィールドを作成するには、変数を使用する必要があります。

例えば

SELECT  col_a,
        fk,
        @r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
        @fk:= fk
FROM    table_one, 
        (SELECT @fk:= 0) fk,
        (SELECT @r:= 0) r
ORDER BY fk, col_a;

戻ります

+-------+----+-----------+
| col_a | fk | RowNumber |
+-------+----+-----------+
|  A    | 4  |    1      |
|  B    | 4  |    2      |
|  C    | 4  |    3      |
+-------+----+-----------+

ここでは、最初に分割フィールドで順序付けする必要があります。たとえば、行番号をそれぞれの行番号を 1 にリセットする場合は、最初にfkこれで順序付けする必要があります。次に、次の順序によって、が適用される順序が決定RowNumberされます。したがって、次のように変更した場合:

ORDER BY fk, col_a DESC;

あなたは得るでしょう:

+-------+----+-----------+
| col_a | fk | RowNumber |
+-------+----+-----------+
|  C    | 4  |    1      |
|  B    | 4  |    2      |
|  A    | 4  |    3      |
+-------+----+-----------+

A と C の RowNumbers が異なることに注意してください

したがって、両方のテーブルに対して同じことを行うと、 と を結合できfkますRowNumber

SELECT  b.fk, CONCAT(COALESCE(a.col_a, ''), '_', COALESCE(b.Col_b, '')) AS ColA_ColB
FROM    (   SELECT  col_b,
                    fk,
                    @r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
                    @fk:= fk
            FROM    table_two, 
                    (SELECT @fk:= 0) fk,
                    (SELECT @r:= 0) r
            ORDER BY fk, col_b
        ) b
        LEFT JOIN
        (   SELECT  col_a,
                    fk,
                    @r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
                    @fk:= fk
            FROM    table_one, 
                    (SELECT @fk:= 0) fk,
                    (SELECT @r:= 0) r
            ORDER BY fk, col_a
        ) a
            ON b.fk = a.fk
            AND b.RowNumber = a.RowNumber;

SQL Fiddle の例

どのテーブルがより多くのレコードを含むか分からない場合、MySQL は完全な結合をサポートしていないため、クエリが少し複雑になるためUNION ALL、データセットをマージする必要があります。

SELECT  a.fk,
        a.RowNumber,
        CONCAT(MAX(CASE WHEN TableSource = 1 THEN Col ELSE '' END), 
                '_',
                MAX(CASE WHEN TableSource = 2 THEN Col ELSE '' END)) AS Col_AB
FROM    ((  SELECT  col_b AS Col,
                    fk,
                    @r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
                    @fk:= fk,
                    2 AS TableSource
            FROM    table_two, 
                    (SELECT @fk:= 0) fk,
                    (SELECT @r:= 0) r
            ORDER BY fk, col_b
        )
        UNION ALL
        (   SELECT  col_a,
                    fk,
                    @r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
                    @fk:= fk,
                    1 AS TableSource
            FROM    table_one, 
                    (SELECT @fk:= 0) fk,
                    (SELECT @r:= 0) r
            ORDER BY fk, col_a
        )) a
GROUP BY a.fk, a.RowNumber;

SQL Fiddle の例


編集

Andriy Mのおかげで、これら 2 つのクエリは次のように整理できます。

  • 結合方法:

    SELECT  b.fk, CONCAT(COALESCE(a.col_a, ''), '_', COALESCE(b.Col_b, '')) AS ColA_ColB
    FROM    (   SELECT  col_b,
                        @r:= (@fk = fk) * @r + 1 AS RowNumber,
                        @fk:= fk AS fk
                FROM    table_two, 
                        (SELECT @fk:= 0, @r:= 0) r
                ORDER BY fk, col_b
            ) b
            LEFT JOIN
            (   SELECT  col_a,
                        @r:= (@fk = fk) * @r + 1 AS RowNumber,
                        @fk:= fk AS fk
                FROM    table_one, 
                        (SELECT @fk:= 0, @r:= 0) r
                ORDER BY fk, col_a
            ) a
                ON b.fk = a.fk
                AND b.RowNumber = a.RowNumber;
    
  • UNION メソッド:

    SELECT  a.fk,
            a.RowNumber,
            CONCAT(MAX(CASE WHEN TableSource = 1 THEN Col ELSE '' END), 
                    '_',
                    MAX(CASE WHEN TableSource = 2 THEN Col ELSE '' END)) AS Col_AB
    FROM    ((  SELECT  col_b AS Col,
                        @r:= (@fk = fk) * @r + 1 AS RowNumber,
                        @fk:= fk AS fk,
                        2 AS TableSource
                FROM    table_two, 
                        (SELECT @fk:= 0, @r:= 0) s
                ORDER BY fk, col_b
            )
            UNION ALL
            (   SELECT  col_a,
                        @r:= (@fk = fk) * @r + 1 AS RowNumber,
                        @fk:= fk AS fk,
                        1 AS TableSource
                FROM    table_one, 
                        (SELECT @fk:= 0, @r:= 0) s
                ORDER BY fk, col_a
            )) a
    GROUP BY a.fk, a.RowNumber;
    

SQL Fiddle の例

于 2013-10-30T11:51:15.657 に答える