簡體   English   中英

MYSQL如何映射這些聯接結果?

[英]MYSQL how to map these join results?

我有這些表:

Objects
ID | Name
----------
1    name1

Tags
ID | ObjectId | Tag
--------------------
1    1          tag1
2    1          tag2

Attributes
ID | ObjectId | Key | Value
--------------------
1    1          key1  value1  
2    1          key2  value2

我想檢索這些值並將它們映射到我的應用程序代碼中的單個對象中。 像這樣:

id: 1,
name: name1,
tags: [tag=tag1, tag=tag2],
attributes: [{key=key1, value=value1}, {key=key2, value=value2}]

但是,此聯接查詢與我預期的不太一樣:

SELECT      o.id, o.name, t.tag, a.key, a.value 
FROM        objects o 
LEFT JOIN   attributes a on a.ObjectId = o.id
LEFT JOIN   tags t on t.ObjectId = o.id
WHERE       o.id = 1

它給了我這4個結果:

1 | key1 | value1 | tag1
1 | key2 | value2 | tag1
1 | key1 | value1 | tag2
1 | key2 | value2 | tag2

這讓我感到驚訝,因為我期望一半的Attribute和一半的Tags結果為null

當我在應用程序代碼中映射它時,最終會得到重復的值,因為我無法知道是否應該多次執行tag1事情。

我應該如何查詢這些數據,以便可以在應用程序代碼中映射到這樣的對象?

您可以使用GROUP_CONCAT()獲得所需的內容。 使用DISTINCT修飾符刪除重復項。

SELECT o.id, o.name, 
        GROUP_CONCAT(DISTINCT t.tag) AS tags, 
        GROUP_CONCAT(DISTINCT CONCAT(a.key, '=', a.value)) AS attributes
FROM object AS o
LEFT JOIN   attributes a on a.ObjectId = o.id
LEFT JOIN   tags t on t.ObjectId = o.id
WHERE       o.id = 1

然后,您可以在應用程序語言中拆分這些逗號分隔和相等分隔的字符串。

或者,您可以使用現有查詢,並合並應用程序語言中的相關行。

如果輸入表中有重復項,如果您需要結果包含重復項,請與使用GROUP_CONCAT子查詢一起加入:

SELECT o.id, o.name, t.tags, a.attributes
FROM object AS o
LEFT JOIN (
    SELECT ObjectId, GROUP_CONCAT(key, '-', value) AS attributes
    FROM attributes
    GROUP BY ObjectId
) AS a ON a.ObjectId = o.id
LEFT JOIN (
    SELECT ObjectId, GROUP_CONCAT(tag) AS tags
    FROM tags
    GROUP BY OBjectId
) AS t ON a.ObjectId = t.id
WHERE o.id = 1

MySQL 8及更高版本具有本機JSON支持,因此您可以執行以下操作:

SELECT      o.ID, o.Name, t.tags, a.attributes
FROM        Objects o
LEFT JOIN   (SELECT ObjectId, JSON_ARRAYAGG(Tag) tags FROM Tags GROUP BY ObjectId) t
            ON t.ObjectId = o.ID
LEFT JOIN   (SELECT ObjectId, JSON_OBJECTAGG(`Key`, `Value`) attributes FROM Attributes GROUP BY ObjectId) a
            ON a.ObjectId = o.ID
WHERE       o.ID = 1;

導致

| ID  | Name  | tags             | attributes                           |
| --- | ----- | ---------------- | ------------------------------------ |
| 1   | name1 | ["tag1", "tag2"] | {"key1": "value1", "key2": "value2"} |

在數據庫小提琴上查看

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM