使用布尔值行到MySQL中的列

时间:2017-12-09 19:59:36

标签: mysql sql database relational-database

我正在尝试构建一个SQL语句(用于MySQL)来解决以下问题:

我有一张表 transport_table ,其中包含从哪个位置传输到其他位置的信息。此表按transport_from(升序)排序,然后按transport_to(升序)排序。有些地方可能只收到货物,有些地方只能发货,大多数地点都可以发送和接收货物。也可以将货物发送到自己的位置。

---------------------------------
| transport_from | transport_to |
-----------------+---------------
| 1              | 2            |
-----------------+---------------
| 1              | 3            |
-----------------+---------------
| 1              | 7            |
-----------------+---------------
| 3              | 3            |
-----------------+---------------
| 3              | 5            |
-----------------+---------------
| 4              | 5            |
-----------------+---------------
| 4              | 6            |
-----------------+---------------
| 4              | 7            |
-----------------+---------------
| 5              | 3            |
-----------------+---------------
| 7              | 1            |
-----------------+---------------
| 7              | 6            |
---------------------------------

但是我需要另一种格式的表格,如果可以通过MySQL实现它会很棒(如果不可能,我仍然可以使用真正的编程语言)。如果两个位置之间有传输,你能帮助我如何找到一个表示布尔值的表。为了实现这一点,我需要将行传输到列,并在原始表中存在特定行时设置布尔值。但我不知道如何实现这一目标。 这样的表应该如下所示:

----------------------------------
| id | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
-----+---+---+---+---+---+---+----
|  1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
-----+---+---+---+---+---+---+----
|  2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-----+---+---+---+---+---+---+----
|  3 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
-----+---+---+---+---+---+---+----
|  4 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
-----+---+---+---+---+---+---+----
|  5 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
-----+---+---+---+---+---+---+----
|  6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-----+---+---+---+---+---+---+----
|  7 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
----------------------------------

如果你帮助我解决这个问题会很棒。非常感谢你!

1 个答案:

答案 0 :(得分:0)

假设行代表TRANSPORT_FROM而列代表TRANSPORT_TO(因为这似乎就是您的意思),请尝试:

SELECT A.TRANSPORT_FROM,
MAX(CASE WHEN TRANSPORT_TO = 1 THEN 1 ELSE 0 END) AS TO_1,
MAX(CASE WHEN TRANSPORT_TO = 2 THEN 1 ELSE 0 END) AS TO_2,
MAX(CASE WHEN TRANSPORT_TO = 3 THEN 1 ELSE 0 END) AS TO_3,
MAX(CASE WHEN TRANSPORT_TO = 4 THEN 1 ELSE 0 END) AS TO_4,
MAX(CASE WHEN TRANSPORT_TO = 5 THEN 1 ELSE 0 END) AS TO_5,
MAX(CASE WHEN TRANSPORT_TO = 6 THEN 1 ELSE 0 END) AS TO_6,
MAX(CASE WHEN TRANSPORT_TO = 7 THEN 1 ELSE 0 END) AS TO_7
FROM
(SELECT DISTINCT TRANSPORT_FROM FROM TRANSPORT_TABLE UNION SELECT DISTINCT TRANSPORT_TO FROM TRANSPORT_TABLE) A
LEFT JOIN
TRANSPORT_TABLE B
ON A.TRANSPORT_FROM = B.TRANSPORT_FROM
GROUP BY A.TRANSPORT_FROM;

我在内部查询中完成了一个UNION,以填充TRANSPORT_FROM的缺失ID(2和6)。您还可以通过创建包含所有TRANSPORT_FROM ID的虚拟表并使用该表代替别名A表示的内部查询来执行此操作。

编辑让它变得动态 我不确定这是否有效,但我尝试了一个至少应该给出方向的版本。

SELECT
GROUP_CONCAT(
    CONCAT(
    ' MAX(CASE WHEN TRANSPORT_TO = ',
    t.TRANSPORT_TO,
    ' THEN 1 ELSE 0 END) AS TO_',
    t.TRANSPORT_TO
    )
) INTO @PivotQuery
FROM
(SELECT TRANSPORT_TO FROM TRANSPORT_TABLE GROUP BY TRANSPORT_TO) t;

SET @PivotQuery = CONCAT('SELECT TRANSPORT_FROM,', @PivotQuery, ' FROM TRANSPORT_TABLE GROUP BY TRANSPORT_FROM ORDER BY TRANSPORT_FROM');


PREPARE statement FROM @PivotQuery;
EXECUTE statement;
DEALLOCATE PREPARE statement;