【问题标题】:SQLite Join multiple tables ordering by less COUNTSQLite 连接多个表,按更少的 COUNT 排序
【发布时间】:2018-07-02 00:47:08
【问题描述】:

我有这个数据库结构:

我需要显示users,它可以在某一天执行确定类型的Task,首先显示分配给较少Tasks(或没有任何Task)的结果那天。

例如:

  • User A 当天分配了 1 个类型为 1 的 Task
  • User B 当天分配了 3 个类型为 1 的 Task
  • User C 当天没有分配类型 1 的 Task

我想按以下顺序显示它们:用户 C > 用户 A > 用户 B

这是我的查询:

SELECT  *, COUNT(*)
FROM USER U
INNER JOIN USER_TASK_TYPE UT ON (U._id=UT.user_id)
LEFT JOIN TASK T ON (U._id = T.user_id)
where UT.TASK_TYPE_ID = ?
where T.CREATION_DATE = ?
GROUP BY T.user_id
ORDER BY COUNT(*) ASC;

仍然有问题,因为如果一个 User 分配了 1 个任务,而另一个 User 没有分配任务,则仍然首先显示第一个 User

如果有任何帮助,我将不胜感激。谢谢。

【问题讨论】:

    标签: sqlite join group-by count


    【解决方案1】:

    首先,提供的架构不反映正在使用的查询:-

    • task 表中没有 creation_date 列。
    • user 表的 id 列应为 _id

    由于WHERE被编码两次,您提供的第二次查询将导致语法错误。

    您对存在哪些数据的描述不清楚,例如你说:-

    用户 A 当天分配了 1 个类型为 1 的任务

    什么行存在于哪个表中?

    作为猜测已经使用了以下内容

    • 注意:-
      • 存在多个没有任务的用户
      • 并且存在当天没有任务的用户

    :-

    -- DROP and Recreate/Create tables
    DROP TABLE IF EXISTS user;
    DROP TABLE IF EXISTS task;
    DROP TABLE IF EXISTS task_type;
    DROP TABLE IF EXISTS user_task_type;
    CREATE TABLE IF NOT EXISTS user (_id INTEGER PRIMARY KEY,  name TEXT, user_id INTEGER, user_name TEXT, password TEXT, user_type TEXT);
    CREATE TABLE IF NOT EXISTS task(id INTEGER PRIMARY KEY, creation_date TEXT, description TEXT, duration int, status TEXT, user_id INTEGER, task_type_id INTEGER);
    CREATE TABLE IF NOT EXISTS task_type(id INTEGER PRIMARY KEY, name TEXT);
    CREATE TABLE IF NOT EXISTS user_task_type (id INTEGER PRIMARY KEY, user_id INTEGER, task_type_id INTEGER);
    
    -- Add some users
    INSERT INTO user (name,password,user_type) VALUES
        ('USER1','x','x'),('USER2','x','x'),('USER3','x','x'),('USER4','x','x'),('USER5','x','x'); 
    
    -- Add some task types
    INSERT INTO task_type (name) VALUES
        ('Sweep'),('Wash'),('Polish'),('Scrub');
    
    -- Add some tasks for users
    INSERT INTO task (creation_date, description, duration, status, user_id, task_type_id) VALUES
        ('2018-01-01','USER1 TASK01',10,'to be done', 1,1),
        ('2018-01-01','USER2 TASK01',10,'to be done', 2,1),
        ('2018-01-01','USER2 TASK01',10,'to be done', 2,1),
        ('2018-01-01','USER2 TASK01',10,'to be done', 2,1),
        ('2018-02-02', 'USER3 NOT ON THE DAY',10,'to be done another day',3,1) --<<<< for testing user on another day
        -- ('2018-01-01','???????',10,'????????',3,1); commented out used for testing
        ;
    
    -- unclear what this is used for but match tasks SUPERFLUOUS?
    INSERT INTO user_task_type (user_id, task_type_id) VALUES
        (1,1),(2,1),(2,1),(2,1),(3,1),
        (3,1) -- added a spurious row;
        ;
    
    SELECT  *, COUNT(*)
    FROM USER U
        JOIN USER_TASK_TYPE UT ON (U._id=UT.user_id)
        JOIN TASK T ON (U._id = T.user_id)
    WHERE UT.TASK_TYPE_ID = 1
    -- WHERE T.CREATION_DATE = '2018-01-01' <<<<<<<<<< Invalid used the following line
    AND T.CREATION_DATE = '2018-01-01' -- <<<<<<<<<< assumed AND
    GROUP BY T.user_id
    ORDER BY COUNT(*) ASC;
    

    结果似乎符合预期(对于当天没有任务或没有任务的用户没有虚假行)。但是,计数并不像预期的那样,而是计数的平方。 :-

    我认为计数的问题在于/使用 user_task_type 表,这似乎是多余的和有问题的。因此,以下内容很可能符合您的要求:-

    SELECT  *, COUNT(*)
    FROM USER U
        -- INNER JOIN USER_TASK_TYPE UT ON (U._id=UT.user_id)
        JOIN TASK T ON (U._id = T.user_id)
        JOIN task_type tt ON tt.id = t.task_type_id
    WHERE  tt.id = 1 AND T.CREATION_DATE = '2018-01-01'
    GROUP BY T.user_id
    ORDER BY COUNT(*) ASC;
    

    这导致:-

    • 即user_task_type 表尚未加入,因为它似乎没有任何用途,并且计数符合预期

    【讨论】:

      猜你喜欢
      • 2014-12-08
      • 1970-01-01
      • 2016-01-08
      • 2020-06-19
      • 2016-07-19
      • 1970-01-01
      • 2016-02-01
      • 2011-01-18
      相关资源
      最近更新 更多