Knex.js 从逗号分隔获取值

Knex.js Getting values from comma-separated

我有两个 SQlite3 tables tasktags

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;