Zoho & SQL - 如何从分组依据和(子)分组依据中获取最小值

Zoho & SQL - How to get min value from group by and (sub)group by

我必须编写一个查询,以获取日期最短的每个项目的里程碑。 我的数据集如下所示:

项目table

    +----+-------+-----------+
    | ID | NAME  |   OTHERS  | 
    +----+-------+-----------+
    |  1 | A     |  W        | 
    |  2 | B     |  X        | 
    |  3 | C     |  Y        | 
    |  4 | D     |  Z        | 
    |... | ...   |  ...      | 
    +----+-------+-----------+

里程碑table

    +----+-------+-----------+
    | ID | NAME  | PROJECTID | 
    +----+-------+-----------+
    | 11 | A1    |  1        | 
    | 21 | B1    |  1        | 
    | 31 | C1    |  2        | 
    | 41 | D1    |  3        | 
    | 51 | E1    |  3        | 
    +----+-------+-----------+

AND 任务 table

    +----+-------+-----------+-------------+
    | ID | MILEID| PROJECTID | DATE        |
    +----+-------+-----------+-------------+
    |111 | 11    |  1        | 18/02/2022  |
    |121 | 11    |  1        | 20/03/2022  |
    |131 | 21    |  1        | 20/06/2022  |
    |141 | 21    |  1        | 01/03/2022  |
    |211 | 31    |  2        | 15/06/2021  |
    |311 | 41    |  3        | 10/05/2021  |
    |312 | 41    |  3        | 30/07/2022  |
    |321 | 51    |  3        | 05/01/2022  |
    |322 | 51    |  3        | 11/04/2022  |
    +----+-------+-----------+-------------+

预期结果是:

    +-----+-------+
    | PID | MID   |    
    +-----+-------+
    |  1  | 11    |    (because 18/02/2022 is the min date all over tasks)
    |  2  | 31    |
    |  3  | 41    |    (because 10/05/2021 is the min date all over tasks)
    +-----+-------+

如您所见,每个里程碑有多个任务,每个项目有多个里程碑。 在我的所有测试中,我的查询 return 每个项目的所有里程碑都不是我需要的。 我不得不说我正在使用 Zoho project Analytics,所以它只支持标准查询(不支持 CTE 或其他)并且只支持 2 级查询。 非常感谢您的帮助。

我对 Zoho 一无所知,但有几种标准方法,我想到的前两种是...


相关Sub-Query:

SELECT
  id     AS pid,
  (
    SELECT TOP 1 task.id
      FROM task
     WHERE task.projectid = project.id
  ORDER BY task.date DESC
  )
    AS mid
FROM
  project

Window 函数 (ROW_NUMBER()):

SELECT
  task_sorted.*
FROM
(
  SELECT task.*,
         ROW_NUMBER() OVER (PARTITION BY task.projectid ORDER BY task.date) AS project_task_row
    FROM task
)
  AS task_sorted
WHERE
  task_sorted.project_task_row = 1

哦,还有连接方法...

SELECT
  task.*
FROM
  task
INNER JOIN
(
  SELECT projectid, MIN(date) AS date
    FROM task
GROUP BY project_id
)
  AS first_task
    ON  first_task.projectid = task.projectid
    AND first_tast.date      = task.date

注意:如果一个项目有多个共享同一日期的任务...

  • 前两个查询会任意取一个
  • 最终查询将return全部

对ZOHO一无所知但是

SELECT 
       T.ProjectID AS [PID]
       ,T.MileID AS [MID]
FROM
       Tasks AS T 
  JOIN
       (/*Get the earliest date for each project*/
       SELECT
               T.ProjectID
              ,MIN(T.Date) AS [minDate]
       FROM
              Tasks AS T
       GROUP BY
              T.ProjectID
       ) AS MinTask ON MinTask.ProjectID = T.ProjectID
       AND MinTask.minDate = T.Date /*This gets the Task ID for the min date for the project*/

此代码假定项目中的日期没有关联。如果您有绑定日期,您将需要另一种方法来消除 MIN 记录的歧义,最好的建议是在外部查询中使用 RANK() OVER() 作为 RANK 值 = 1

的过滤器
SELECT 
       T.ProjectID AS [PID]
       ,T.MileID AS [MID]
FROM
       Tasks AS T 
  JOIN
       (/*Get the earliest date for each project*/
       SELECT
               T.ProjectID
              ,MIN(T.Date) AS [minDate]
       FROM
              Tasks AS T
       GROUP BY
              T.ProjectID
       ) AS MinTask ON MinTask.ProjectID = T.ProjectID
       AND MinTask.minDate = T.Date /*This gets the Task ID for the min date for the project*/
WHERE
      RANK() OVER(PARTITION BY T.ProjectID,T.Date ORDER BY T.MileID) = 1

这个有用吗?

SELECT
     T.ProjectID
       ,MIN(T.MileID) AS MileID
FROM
     Tasks AS T
  JOIN
       (
       SELECT
               ProjectID
               ,MIN(Date) AS MinDate
       FROM
             Tasks
       GROUP BY
               ProjectID
     ) AS FirstDate ON FirstDate.ProjectID = T.ProjectID
       AND FirstDate.MinDate = T.Date
GROUP BY
       T.ProjectID

子select将获得每个项目的最低日期 外部 select 将获得里程碑日期与最低项目日期匹配的项目的最低里程碑 ID。