Knex.js从逗号分隔获取值

时间:2019-09-04 00:30:45

标签: sql sqlite knex.js

我有两个SQlite3表tasktags

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中实际使用它。请帮帮我。

2 个答案:

答案 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;