Knex.js 从逗号分隔获取值
Knex.js Getting values from comma-separated
我有两个 SQlite3 tables task
和 tags
task
是我的主人 table 而 tags
是存储标签名称
我将逗号分隔值存储在 task
中
现在我想通过 knex.js
获得 Tag names
table task
id task tags
---------------------
1 abc 1,2,3
2 xyz 3,1
3 apple 2
table tags
id tag
------------
1 cold
2 hot
3 normal
现在我想要输出如下
输出:
id task tags
---------------------
1 abc cold,hot,normal
2 xyz normal,cold
3 apple hot
我知道我将不得不使用联接,但不确定如何在 knex.js 中实际使用它。请帮帮我。
部分问题是您的数据库没有正确规范化。不是有两个 table 任务和选项卡,table 任务在 'tags' 列中包含多个标签 ID,你应该有三个 table; 'tasks'、'tags' 和 'joining' table 'task_tags'。他们将存储以下数据...
任务
id task
----------
1 abc
2 xyz
3 apple
标签
id tag
------------
1 cold
2 hot
3 normal
task_tags
task_id tag_id
1 1
1 2
1 3
2 1
2 3
3 2
现在您可以拥有任意数量的标签(无论是否有任何任务使用它们)和任意数量的任务(无论它们是否使用任何标签)并且您可以通过task_tags table.
然后要获得您想要的结果,您可以使用 select
SELECT
tasks.id,
tasks.task,
GROUP_CONCAT(tags.tag) -- this gives you the csv line eg cold,hot,normal
from tasks
left join task_tags
ON tasks.id = task_tags.task_id
left join tags
on tags.id = task_tags.tag_id
GROUP BY task.id, tags.id
参见 https://www.sqlite.org/lang_aggfunc.html 了解 GROUP_CONCAT
的解释
您的任务 table 应重新设计为每行包含一个标签,而不是一行包含多个标签:
id task tag
---------- ---------- ----------
1 abc 1
1 abc 2
1 abc 3
2 xyz 3
2 xyz 1
3 apple 2
那就简单了:
SELECT task.id, task.task, group_concat(tags.tag, ',') AS tags
FROM task
JOIN tags ON task.tag = tags.id
GROUP BY task.id, task.task
ORDER BY task.id;
这给出了
id task tags
---------- ---------- ---------------
1 abc cold,hot,normal
2 xyz normal,cold
3 apple hot
遵循关系数据库规则的设计使生活变得更加轻松(并且上述内容可以进一步规范化;参见其他答案);虽然有些数据库确实支持数组类型,但 sqlite 不是其中之一。但是,如果您坚持保留当前的设计,则有一个涉及 JSON1 扩展并将您的 CSV 数字列表转换为 JSON 数组的丑陋黑客:
SELECT task.id, task.task, group_concat(tags.tag, ',') AS tags
FROM task
JOIN json_each('[' || task.tags || ']') AS j
JOIN tags ON tags.id = j.value
GROUP BY task.id, task.task
ORDER BY task.id;
我有两个 SQlite3 tables task
和 tags
task
是我的主人 table 而 tags
是存储标签名称
我将逗号分隔值存储在 task
现在我想通过 knex.js
获得Tag names
table task
id task tags
---------------------
1 abc 1,2,3
2 xyz 3,1
3 apple 2
table tags
id tag
------------
1 cold
2 hot
3 normal
现在我想要输出如下
输出:
id task tags
---------------------
1 abc cold,hot,normal
2 xyz normal,cold
3 apple hot
我知道我将不得不使用联接,但不确定如何在 knex.js 中实际使用它。请帮帮我。
部分问题是您的数据库没有正确规范化。不是有两个 table 任务和选项卡,table 任务在 'tags' 列中包含多个标签 ID,你应该有三个 table; 'tasks'、'tags' 和 'joining' table 'task_tags'。他们将存储以下数据...
任务
id task
----------
1 abc
2 xyz
3 apple
标签
id tag
------------
1 cold
2 hot
3 normal
task_tags
task_id tag_id
1 1
1 2
1 3
2 1
2 3
3 2
现在您可以拥有任意数量的标签(无论是否有任何任务使用它们)和任意数量的任务(无论它们是否使用任何标签)并且您可以通过task_tags table.
然后要获得您想要的结果,您可以使用 select
SELECT
tasks.id,
tasks.task,
GROUP_CONCAT(tags.tag) -- this gives you the csv line eg cold,hot,normal
from tasks
left join task_tags
ON tasks.id = task_tags.task_id
left join tags
on tags.id = task_tags.tag_id
GROUP BY task.id, tags.id
参见 https://www.sqlite.org/lang_aggfunc.html 了解 GROUP_CONCAT
的解释您的任务 table 应重新设计为每行包含一个标签,而不是一行包含多个标签:
id task tag
---------- ---------- ----------
1 abc 1
1 abc 2
1 abc 3
2 xyz 3
2 xyz 1
3 apple 2
那就简单了:
SELECT task.id, task.task, group_concat(tags.tag, ',') AS tags
FROM task
JOIN tags ON task.tag = tags.id
GROUP BY task.id, task.task
ORDER BY task.id;
这给出了
id task tags
---------- ---------- ---------------
1 abc cold,hot,normal
2 xyz normal,cold
3 apple hot
遵循关系数据库规则的设计使生活变得更加轻松(并且上述内容可以进一步规范化;参见其他答案);虽然有些数据库确实支持数组类型,但 sqlite 不是其中之一。但是,如果您坚持保留当前的设计,则有一个涉及 JSON1 扩展并将您的 CSV 数字列表转换为 JSON 数组的丑陋黑客:
SELECT task.id, task.task, group_concat(tags.tag, ',') AS tags
FROM task
JOIN json_each('[' || task.tags || ']') AS j
JOIN tags ON tags.id = j.value
GROUP BY task.id, task.task
ORDER BY task.id;