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 现在不同了

因此,如果您对两个表执行相同的操作,则可以加入fkRowNumber

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,这两个查询可以整理如下:

  • 加入方法:

    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;
    
  • 联合方法:

    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 回答
-1

使用左侧

select concat(col_a,'_',col_b) from 
table_one left outer join table_two using(fk)
于 2013-10-30T11:40:25.807 回答