【问题标题】:Selecting first record only from join table with a where condition仅从具有 where 条件的连接表中选择第一条记录
【发布时间】:2015-07-20 14:45:20
【问题描述】:

我已经使用 PHP 解决了这个问题,但我知道如果我可以查询它会更快。我有以下 2 个表。

projects:     
+------------+--------------+ 
| project_id | project_name | 
+------------+--------------+ 
|  1         | a            | 
|  2         | b            | 
|  3         | c            | 
|  4         | d            | 
+------------+--------------+ 

tasks:
+------------+------------+-------------+---------------------+ 
| project_id |  task_id   | task_status |  task_due_timestamp |
+------------+------------+-------------+---------------------+ 
|      1     |      1     |     1       | 2015-01-01 12:00:00 |
|      1     |      2     |     2       | 2015-01-02 12:00:00 |
|      2     |      3     |     3       | 2015-01-03 12:00:00 |
|      3     |      4     |     1       | 2015-01-04 12:00:00 |
+------------+------------+-------------+---------------------+

我需要一个查询来选择所有项目及其关联任务的状态为 1 或 2。它选择的任务必须是最新的。见下表。

records after query:
+------------+--------------+------------+-------------+---------------------+ 
| project_id | project_name |  task_id   | task_status |  task_due_timestamp |
+------------+--------------+------------+-------------+---------------------+ 
|     1      | a            |      1     |     1       | 2015-01-01 12:00:00 |
|     2      | b            |     null   |    null     |       null          |
|     3      | c            |      3     |     3       | 2015-01-01 12:00:00 |
|     4      | d            |      null  |     null    | null                |
+------------+--------------+------------+-------------+---------------------+

如您所见,项目 2 不应该有任务,因为任务状态为 2。项目 4 没有项目。项目 1 有 2 个任务,但最早的任务提前了一天。

任何帮助将不胜感激。

【问题讨论】:

  • 您如何获得 2015-01-01 12:00:00 记录而不是 2015-01-02 12:00:00?
  • 您必须使用 MAX 运算符来获取最近的任务,然后使用 JOIN 来将任务与项目结合起来。使用 WHERE 选择状态 1 或 2

标签: mysql sql codeigniter


【解决方案1】:

您可以尝试对状态为12 的最新任务进行左连接。查询会是这样的:

select p.*, t.*
from projects as p
  left join (
    select t1.*
    from tasks as t1
    where t1.task_status in (1, 2)
      and not exists (
        select task_id from tasks as t2
        where t1.task_id <> t2.task_id
          and t1.project_id = t2.project_id
          and t2.task_status in (1, 2)
          and t2.task_due_timestamp > t1.task_due_timestamp
      )
  ) as t on p.project_id = t.project_id

Live demo

【讨论】:

    【解决方案2】:

    你可以试试这个:-

    SELECT P.project_id, P.project_name, T.task_id, T.task_status, MIN(T.task_due_timestamp)
    FROM projects P INNER JOIN tasks T 
    ON P.project_id = T.project_id 
    AND T.task_status IN (1,2)
    GROUP BY P.project_id, P.project_name, T.task_id, T.task_status
    

    【讨论】:

    • MIN(T.task_id), MIN(T.task_status), MIN(T.task_due_timestamp) 可以选择不在同一行的 3 个字段。
    • 已接受。我没有仔细阅读问题。我已经编辑了我的答案
    • 你测试过这个查询吗?
    • 这将创建单行组,因此从同一个项目返回多个任务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    相关资源
    最近更新 更多