如何根据另一个表中的json数组值过滤表

时间:2021-03-18 11:05:23

标签: mysql google-cloud-sql

我有 2 张表,一张用于用户,一张用于帖子:

create database db;

create table if not exists db.users
(
    uid       char(10) primary key,
    username  char(10),
    following json,
    blocked   json
);

insert into db.users (uid, username, following, blocked)
VALUES ('uid_0', 'user_0', '["uid_1", "uid_2"]', '["uid_3"]');

insert into db.users (uid, username, following, blocked)
VALUES ('uid_1', 'user_1', '["uid_0", "uid_2", "user_3"]', '[]');

insert into db.users (uid, username, following, blocked)
VALUES ('uid_2', 'user_2', '["uid_0"]', '[]');

insert into db.users (uid, username, following, blocked)
VALUES ('uid_3', 'user_3', '["uid_1"]', '[]');

create table if not exists db.posts
(
    id    char(10) primary key,
    owner char(10),
    text  char(100)
);

insert into db.posts (id, owner, text)
VALUES ('post_0', 'uid_0', 'text_0');

insert into db.posts (id, owner, text)
VALUES ('post_1', 'uid_1', 'text_1');

insert into db.posts (id, owner, text)
VALUES ('post_2', 'uid_2', 'text_2');

insert into db.posts (id, owner, text)
VALUES ('post_3', 'uid_3', 'text_3');

我想要做的是根据以下列表和阻止列表查询一个用户的帖子。

我所能做的就是使用只有 0 到 1000 的数字的标记表将以下列表转换为表。

SET @following = (select following
                  from firestore_mirror.users
                  where uid = 'userId');

SELECT JSON_EXTRACT(@following, CONCAT('$[', helper._row, ']')) as uid
FROM (SELECT @following AS helper) AS A
         INNER JOIN firestore_mirror.t_list_row AS helper
                    ON helper._row < JSON_LENGTH(@following);

这给了我这个

"value_0"
"value_1"
"value_2"
"value_3"
"value_4"

但是当我尝试这个时,我得到的结果是空的

SET @following = (select following
                  from firestore_mirror.users
                  where uid = 'userId');

select *
from firestore_mirror.posts
where owner in (SELECT JSON_EXTRACT(@following, CONCAT('$[', helper._row, ']')) as uid
                FROM (SELECT @following AS helper) AS A
                         INNER JOIN firestore_mirror.t_list_row AS helper
                                    ON helper._row < JSON_LENGTH(@following));

我在 MySql 8.0 中使用 Cloud SQL。

在我的脑海中 (:))) 我期待的结果是

select *
from db.posts
where owner in (select following from db.users where uid = 'uid_0')
  and owner not in (select blocked from db.users where uid = 'uid_0');
id, owner, text
"post_1", "uid_1", "text_1"
"post_2", "uid_2", "text_2"

1 个答案:

答案 0 :(得分:1)

SELECT posts.*
FROM users u1
JOIN users u2 ON JSON_SEARCH(u1.following, 'one', u2.uid)
--           AND JSON_SEARCH(u1.blocked, 'one', u2.uid) IS NULL
JOIN posts ON u2.username = posts.owner
WHERE u1.uid = @uid

如果 uidfollowing 列中可能存在相同的 blocked,并且不得返回该用户拥有的帖子,则取消注释。

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2399bc226e47b3b93e3e5016908677ee