【问题标题】:Knex.js Getting values from comma-separatedKnex.js 从逗号分隔中获取值
【发布时间】:2019-09-04 09:41:45
【问题描述】:

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

【问题讨论】:

    标签: sql sqlite knex.js


    【解决方案1】:

    部分问题是您的数据库未正确规范化。而不是有两个表任务和选项卡,表任务在“标签”列中包含多个标签 ID,你应该有三个表; 'tasks'、'tags' 和 'joining' 表 '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 表将任务与其标签相关联.

    然后为了得到你想要的结果,你可以使用 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
    

    有关 GROUP_CONCAT 的说明,请参阅 https://www.sqlite.org/lang_aggfunc.html

    【讨论】:

    • 我理解它在 SO 上定制,如果它解决了问题,则接受答案。你介意这样做吗?
    【解决方案2】:

    您的任务表应该重新设计为每行包含一个标签,而不是单行中的多个标签:

    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 不是其中之一。但是,如果您坚持保留当前的设计,则有一个丑陋的 hack,涉及到 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多