首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么JSON_TABLE()连接不一致?

为什么JSON_TABLE()连接不一致?
EN

Stack Overflow用户
提问于 2019-11-04 20:51:07
回答 1查看 2.9K关注 0票数 4

在MySQL 8中,我们现在可以使用JSON类型的列,也可以使用内置函数(如JSON_TABLE() ),但正如我在不同的场景中使用的那样,有时我看到了意想不到的结果。

JSON_TABLE()的Docs:https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html

也许JSON_TABLE不是实现与JSON连接的方法。MySQL提供了一些搜索功能,但是没有什么可以替代JSON_TABLE()

用于JSON搜索函数的文档:https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html

模式(MySQL v8.0)

代码语言:javascript
复制
CREATE TABLE USER (
    NAME varchar(128) NOT NULL,
    METADATA JSON NULL
);

INSERT INTO USER VALUES
('John', '[1,3]'),
('Jane', '[2]'),
('Bob', null),
('Sally', '[9]');


CREATE TABLE ROLES (
  ID int NOT NULL,
  NAME varchar(64) NOT NULL
);

INSERT INTO ROLES VALUES
(1, 'Originator'),
(2, 'Approver'),
(3, 'Reviewer');

查询#1 -为什么Bob不返回?

代码语言:javascript
复制
SELECT * 
FROM USER,
JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK;

## Results ##
| NAME  | METADATA | ID  |
| ----- | -------- | --- |
| John  | [1, 3]   | 1   |
| John  | [1, 3]   | 3   |
| Jane  | [2]      | 2   |
| Sally | [9]      | 9   |

查询#2

代码语言:javascript
复制
SELECT * FROM ROLES;

## Results ##
| ID  | NAME       |
| --- | ---------- |
| 1   | Originator |
| 2   | Approver   |
| 3   | Reviewer   |

查询#3 -为什么没有结果?

代码语言:javascript
复制
SELECT * 
FROM USER
JOIN ROLES ON ROLES.id IN (
    SELECT ID FROM JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
    ) AS JSON_ROLE_LINK     
);

##There are no results to be displayed.

查询#4 -不是带有IN()的JOINing返回正确的结果。

代码语言:javascript
复制
SELECT * 
FROM USER,
JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK
JOIN ROLES ON ROLES.ID = JSON_ROLE_LINK.ID;

## Results ##
| NAME | METADATA | ID  | ID  | NAME       |
| ---- | -------- | --- | --- | ---------- |
| John | [1, 3]   | 1   | 1   | Originator |
| John | [1, 3]   | 3   | 3   | Reviewer   |
| Jane | [2]      | 2   | 2   | Approver   |

查询#5 -鲍勃在哪里?

代码语言:javascript
复制
SELECT * 
FROM USER,
JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK
LEFT JOIN ROLES ON ROLES.ID = JSON_ROLE_LINK.ID;

## Results ##
| NAME  | METADATA | ID  | ID  | NAME       |
| ----- | -------- | --- | --- | ---------- |
| John  | [1, 3]   | 1   | 1   | Originator |
| Jane  | [2]      | 2   | 2   | Approver   |
| John  | [1, 3]   | 3   | 3   | Reviewer   |
| Sally | [9]      | 9   |     |            |

查询#6 -当查询3没有返回任何内容时,为什么LEFT ()返回预期结果?

代码语言:javascript
复制
SELECT * 
FROM USER
LEFT JOIN ROLES ON ROLES.id IN (
    SELECT ID FROM JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
    ) AS JSON_ROLE_LINK     
);

## Results ##
| NAME  | METADATA | ID  | NAME       |
| ----- | -------- | --- | ---------- |
| John  | [1, 3]   | 1   | Originator |
| John  | [1, 3]   | 3   | Reviewer   |
| Jane  | [2]      | 2   | Approver   |
| Bob   |          |     |            |
| Sally | [9]      |     |            |

关于DB Fiddle的看法

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-12 10:27:52

使用ISNULL属性创建虚拟json

代码语言:javascript
复制
SELECT * 
FROM USER,
JSON_TABLE(
      IFNULL(USER.METADATA,'[0]'), "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK;

DB小提琴

代码语言:javascript
复制
#1 No JOINS with JSON_TABLE where is Bob?
SELECT * 
FROM USER,
JSON_TABLE(
      IFNULL(USER.METADATA,'[0]'), "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK;

#2 Verify our ROLE recrods exist
SELECT * FROM ROLES;

#3 Regular JOIN with JSON_TABLE inside the IN(), why are there no results?
SELECT * 
FROM USER
JOIN ROLES ON ROLES.id IN (
    SELECT ID FROM USER, JSON_TABLE(
      USER.METADATA, "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
    ) AS JSON_ROLE_LINK     
);

#4 Regular JOIN with JSON_TABLE, returns expected results
SELECT * 
FROM USER,
JSON_TABLE(
      IFNULL(USER.METADATA,'[0]'), "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK
JOIN ROLES ON ROLES.ID = JSON_ROLE_LINK.ID;

#5 LEFT JOIN with JSON_TABLE, where is Bob?
SELECT * 
FROM USER,
JSON_TABLE(
      IFNULL(USER.METADATA,'[0]'), "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
) AS JSON_ROLE_LINK
LEFT JOIN ROLES ON ROLES.ID = JSON_ROLE_LINK.ID;

#6 LEFT JOIN with JSON_TABLE inside the IN(), returns expected results
SELECT * 
FROM USER
LEFT JOIN ROLES ON ROLES.id IN (
    SELECT ID FROM JSON_TABLE(
      IFNULL(USER.METADATA,'[0]'), "$[*]" 
      COLUMNS(ID int PATH "$" NULL ON ERROR NULL ON EMPTY)
    ) AS JSON_ROLE_LINK     
);
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58700849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档