mysql >5.7 JOIN 两个 json 表只返回最后一个唯一条目
mysql >5.7 JOIN two json tables returning only last unique entry
我希望使用联接将引用替换为以下 mysql
中的值
最终函数的输出应该是
{"Fav_Friend": "Ross", "castMember": "Elaine"}
{"Fav_Friend": "Gina", "castMember": "George"}
{"Fav_Friend": "Gina", "castMember": "Jerry"}
{"Fav_Friend": "Monica", "castMember": "Kramer"}
{"Fav_Friend": "Rachel", "castMember": "Numan"}
请注意我们正在更改此函数
the key names -> works ok,
name->castmember
favfriend->Fav_Friend
get last unique row that matches $.name -> works OK
eg: {"Fav_Friend": "c1fcb509e6b34e5ba5d0a44329a88a94", "castMember": "Elaine"}
WITH lastEntry AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY details->>'$.name' ORDER BY uid DESC) AS lE
FROM people AS m
) SELECT
JSON_OBJECT('castMember',details->>'$.name','Fav_Friend',details->>'$.favfriend')
FROM lastEntry WHERE lE = 1;
在 SO 上查看其他答案我尝试添加 LEFT JOIN
+ CAST
但是这个 returns 是一个错误
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN friends g on JSON_CONTAINS(m.details->>'$.favfriend', CAST(g.crew-' at line 6
WITH lastEntry AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY details->>'$.name' ORDER BY uid DESC) AS lE
FROM people AS m
) SELECT
JSON_OBJECT('castMember',details->>'$.name','Fav_Friend',details->>'$.favfriend')
FROM lastEntry WHERE lE = 1
LEFT JOIN friends g on JSON_CONTAINS(m.details->>'$.favfriend', CAST(g.crew->>'$.screen' as JSON), '$');
也试过直接引用
LEFT JOIN friends g on JSON_CONTAINS(lastEntry.details->>'$.favfriend', CAST(g.crew->>'$.screen' as JSON), '$');
如果这是错误的方向,我也尝试了
的变体
LEFT JOIN friends g on people.details->>'$.favfriend' = g.crew->>'$.screen';
如何用 screen
名称替换 guid
?
这是table数据
CREATE DATABASE castfriends
DEFAULT CHARACTER SET = 'utf8mb4';
use castfriends;
CREATE TABLE `people` (
`uid` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`details` json DEFAULT NULL COMMENT 'supporting fields for parent',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb3;
insert into castfriends.people (details) values
(
'{
"guid" : "c14ad6a7e63a4f6c8d68b4bc3a3dd404",
"name": "George",
"favfriend":"062a55f932ea408e8f8f1914f1499a24"
}'
),
(
'{
"guid" : "f4aec5a0043f4933a084cea137ebcff9",
"name": "Elaine",
"favfriend":"d8930c49405242d5923362b8818b93ad"
}'
),
(
'{
"guid" : "c788335702eb413496c7d60e7041c34c",
"name": "Jerry",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "30425947838149fda9f836a089605459",
"name": "Kramer",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "18dc6c62c2554ef796c684164d72eee0",
"name": "Numan",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "c15ea8d20f8d4906a1d9704e347e5d81",
"name": "Elaine",
"favfriend":"c1fcb509e6b34e5ba5d0a44329a88a94"
}'
),
(
'{
"guid" : "975f1fdc11a64d4ba716513f5d08c23d",
"name": "Jerry",
"favfriend":"062a55f932ea408e8f8f1914f1499a24"
}'
),
(
'{
"guid" : "f1fb99a8ac1342c5b266af44dfa92db1",
"name": "Kramer",
"favfriend":"49578c5a85a1454597b911e8c6300828"
}'
),
(
'{
"guid" : "feeab20a78bd4297aa8a920c91760d8b",
"name": "Numan",
"favfriend":"d8930c49405242d5923362b8818b93ad"
}'
);
use castfriends;
CREATE TABLE `friends` (
`uid` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`crew` json DEFAULT NULL COMMENT 'supporting fields for parent',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb3;
insert into castfriends.friends (crew) values
(
'{
"guid" : "d8930c49405242d5923362b8818b93ad",
"screen": "Rachel"
}'
),
(
'{
"guid" : "49578c5a85a1454597b911e8c6300828",
"screen": "Monica"
}'
),
(
'{
"guid" : "a846ec1c09844012bb1d3e64ae311bf8",
"screen": "Ursula"
}'
),
(
'{
"guid" : "c1fcb509e6b34e5ba5d0a44329a88a94",
"screen": "Ross"
}'
),
(
'{
"guid" : "062a55f932ea408e8f8f1914f1499a24",
"screen": "Gina"
}'
);
解析您的 JSON 以分隔列:
SELECT people.uid, p_details.*
FROM people
CROSS JOIN JSON_TABLE( people.details,
'$' COLUMNS ( guid CHAR(32) PATH '$.guid',
name VARCHAR(255) PATH '$.name',
favfriend CHAR(32) PATH '$.favfriend'
)
) p_details;
SELECT friends.uid, f_details.*
FROM friends
CROSS JOIN JSON_TABLE( friends.crew ,
'$' COLUMNS ( guid CHAR(32) PATH '$.guid',
screen VARCHAR(255) PATH '$.screen'
)
) f_details;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ea67858bd8abae43d73224c818ee58d2
使用这些查询作为 CTE 在外部查询中加入它们,应用任何需要的条件,然后重建所需的最终 JSON 值并在 UPDATE 中使用。
您在 LEFT JOIN
之前有一个 WHERE
子句。它需要在...
之后出现
SELECT ... FROM ... JOIN ... WHERE ... GROUP BY ... ORDER BY ...
我希望使用联接将引用替换为以下 mysql
中的值最终函数的输出应该是
{"Fav_Friend": "Ross", "castMember": "Elaine"}
{"Fav_Friend": "Gina", "castMember": "George"}
{"Fav_Friend": "Gina", "castMember": "Jerry"}
{"Fav_Friend": "Monica", "castMember": "Kramer"}
{"Fav_Friend": "Rachel", "castMember": "Numan"}
请注意我们正在更改此函数
the key names -> works ok,
name->castmember
favfriend->Fav_Friend
get last unique row that matches $.name -> works OK
eg: {"Fav_Friend": "c1fcb509e6b34e5ba5d0a44329a88a94", "castMember": "Elaine"}
WITH lastEntry AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY details->>'$.name' ORDER BY uid DESC) AS lE
FROM people AS m
) SELECT
JSON_OBJECT('castMember',details->>'$.name','Fav_Friend',details->>'$.favfriend')
FROM lastEntry WHERE lE = 1;
在 SO 上查看其他答案我尝试添加 LEFT JOIN
+ CAST
但是这个 returns 是一个错误
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN friends g on JSON_CONTAINS(m.details->>'$.favfriend', CAST(g.crew-' at line 6
WITH lastEntry AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY details->>'$.name' ORDER BY uid DESC) AS lE
FROM people AS m
) SELECT
JSON_OBJECT('castMember',details->>'$.name','Fav_Friend',details->>'$.favfriend')
FROM lastEntry WHERE lE = 1
LEFT JOIN friends g on JSON_CONTAINS(m.details->>'$.favfriend', CAST(g.crew->>'$.screen' as JSON), '$');
也试过直接引用
LEFT JOIN friends g on JSON_CONTAINS(lastEntry.details->>'$.favfriend', CAST(g.crew->>'$.screen' as JSON), '$');
如果这是错误的方向,我也尝试了
的变体LEFT JOIN friends g on people.details->>'$.favfriend' = g.crew->>'$.screen';
如何用 screen
名称替换 guid
?
这是table数据
CREATE DATABASE castfriends
DEFAULT CHARACTER SET = 'utf8mb4';
use castfriends;
CREATE TABLE `people` (
`uid` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`details` json DEFAULT NULL COMMENT 'supporting fields for parent',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb3;
insert into castfriends.people (details) values
(
'{
"guid" : "c14ad6a7e63a4f6c8d68b4bc3a3dd404",
"name": "George",
"favfriend":"062a55f932ea408e8f8f1914f1499a24"
}'
),
(
'{
"guid" : "f4aec5a0043f4933a084cea137ebcff9",
"name": "Elaine",
"favfriend":"d8930c49405242d5923362b8818b93ad"
}'
),
(
'{
"guid" : "c788335702eb413496c7d60e7041c34c",
"name": "Jerry",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "30425947838149fda9f836a089605459",
"name": "Kramer",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "18dc6c62c2554ef796c684164d72eee0",
"name": "Numan",
"favfriend":"a846ec1c09844012bb1d3e64ae311bf8"
}'
),
(
'{
"guid" : "c15ea8d20f8d4906a1d9704e347e5d81",
"name": "Elaine",
"favfriend":"c1fcb509e6b34e5ba5d0a44329a88a94"
}'
),
(
'{
"guid" : "975f1fdc11a64d4ba716513f5d08c23d",
"name": "Jerry",
"favfriend":"062a55f932ea408e8f8f1914f1499a24"
}'
),
(
'{
"guid" : "f1fb99a8ac1342c5b266af44dfa92db1",
"name": "Kramer",
"favfriend":"49578c5a85a1454597b911e8c6300828"
}'
),
(
'{
"guid" : "feeab20a78bd4297aa8a920c91760d8b",
"name": "Numan",
"favfriend":"d8930c49405242d5923362b8818b93ad"
}'
);
use castfriends;
CREATE TABLE `friends` (
`uid` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`crew` json DEFAULT NULL COMMENT 'supporting fields for parent',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb3;
insert into castfriends.friends (crew) values
(
'{
"guid" : "d8930c49405242d5923362b8818b93ad",
"screen": "Rachel"
}'
),
(
'{
"guid" : "49578c5a85a1454597b911e8c6300828",
"screen": "Monica"
}'
),
(
'{
"guid" : "a846ec1c09844012bb1d3e64ae311bf8",
"screen": "Ursula"
}'
),
(
'{
"guid" : "c1fcb509e6b34e5ba5d0a44329a88a94",
"screen": "Ross"
}'
),
(
'{
"guid" : "062a55f932ea408e8f8f1914f1499a24",
"screen": "Gina"
}'
);
解析您的 JSON 以分隔列:
SELECT people.uid, p_details.*
FROM people
CROSS JOIN JSON_TABLE( people.details,
'$' COLUMNS ( guid CHAR(32) PATH '$.guid',
name VARCHAR(255) PATH '$.name',
favfriend CHAR(32) PATH '$.favfriend'
)
) p_details;
SELECT friends.uid, f_details.*
FROM friends
CROSS JOIN JSON_TABLE( friends.crew ,
'$' COLUMNS ( guid CHAR(32) PATH '$.guid',
screen VARCHAR(255) PATH '$.screen'
)
) f_details;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ea67858bd8abae43d73224c818ee58d2
使用这些查询作为 CTE 在外部查询中加入它们,应用任何需要的条件,然后重建所需的最终 JSON 值并在 UPDATE 中使用。
您在 LEFT JOIN
之前有一个 WHERE
子句。它需要在...
SELECT ... FROM ... JOIN ... WHERE ... GROUP BY ... ORDER BY ...