我有两个SQlite3表task
和tags
task
是我的主表,tags
存储标签名
我将逗号分隔的值存储在task
现在我想使用knex.js来获取Tag names
表task
id task tags
---------------------
1 abc 1,2,3
2 xyz 3,1
3 apple 2
表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中实际使用它。请帮帮我。
答案 0 :(得分:1)
部分问题是数据库未正确规范化。与具有两个表任务和选项卡的表任务不同,在“标签”列中包含多个标签ID的表任务,应该有三个表。 'tasks','tags'和'joining'表'task_tags'。他们将存储以下数据...
任务
id task
----------
1 abc
2 xyz
3 apple
标签
id tag
------------
1 cold
2 hot
3 normal
任务标签
task_id tag_id
1 1
1 2
1 3
2 1
2 3
3 2
现在,您可以拥有任意数量的标签(无论是否有任何任务使用它们)和任意数量的任务(无论它们是否有使用任何标签),并且可以通过task_tags表将任务与其标签相关联
然后要获得想要的结果,您可以使用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.htm l,以获得GROUP_CONCAT的解释
答案 1 :(得分:1)
您的任务表应重新设计为每行包含一个标签,而不是一行中包含多个标签:
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;