协助SQL多表查询 - 返回重复的结果

时间:2009-07-29 08:28:01

标签: sql

我们使用在线项目管理系统,我试图对其进行一些扩展。

它有以下感兴趣的表格:

todo_itemStatus:
+--------------+-----------------------+------+-----+---------------------+----------------+
| Field        | Type                  | Null | Key | Default             | Extra          |
+--------------+-----------------------+------+-----+---------------------+----------------+
| itemStatusId | bigint(20) unsigned   | NO   | PRI | NULL                | auto_increment |
| itemId       | int(10) unsigned      | NO   | MUL | 0                   |                |
| statusDate   | datetime              | NO   |     | 0000-00-00 00:00:00 |                |
| statusKey    | tinyint(3) unsigned   | NO   |     | 0                   |                |
| memberId     | mediumint(8) unsigned | NO   |     | 0                   |                |
+--------------+-----------------------+------+-----+---------------------+----------------+

此表记录任务何时完成,并保持所有任务更改的状态。

然后是项目表和“项目”(或任务)表。

我基本上希望能够提取项目列表,并详细说明完成任务的百分比。但是,现在我很高兴能够在项目中列出每项任务,并详细说明它们是否完整。

据我所知,获取任务最新状态的最佳方法是选择statusDate最新的todo_itemStatus,或者itemStatusId最大,而itemId等于我感兴趣的任务

我尝试了这样的查询:

<pre>
select todo_item.itemId, todo_item.title, todo_itemStatus.statusKey, todo_itemStatus.statusDate 
from todo_item, todo_project, todo_itemStatus 
where todo_item.projectId  = todo_project.projectId 
and todo_project.projectId = 13 
and todo_itemStatus.itemId = todo_item.itemId 
and todo_itemStatus.statusDate = (
    select MAX(todo_itemStatus.statusDate) 
    from todo_itemStatus key1 where todo_itemStatus.itemId  = key1.itemId);
</pre>

然而,这会产生所有状态更新,输出如下:

+--------+-----------------------------------------------------------------------------+-----------+---------------------+
| itemId | title                                                                       | statusKey | statusDate          |
+--------+-----------------------------------------------------------------------------+-----------+---------------------+
|    579 | test complete item - delete me                                              |         1 | 2009-07-28 13:04:38 |
|    579 | test complete item - delete me                                              |         0 | 2009-07-28 14:12:12 |
+--------+-----------------------------------------------------------------------------+-----------+---------------------+

这不是我想要的,因为我只希望从todo_itemStatus表中的最新条目返回一个带有statusKey / statusDate的任务条目。

我知道我的描述中有点模糊,但我不想写一个很长的消息。如有必要,我可以提供更多细节。

请有人建议我做错了吗?自从我完成了任何真正的数据库工作以来已经很长时间了,所以我有点不确定我在这里做错了什么......

非常感谢! 戴夫

2 个答案:

答案 0 :(得分:1)

您应该考虑使用DISTINCT关键字(Microsoft SQL Server)

编辑:我刚刚重新阅读了您的问题,我认为GROUP BY子句更适合这种情况。您应该阅读http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/,但基本上您需要做的是首先使用GROUP BY子句选择您感兴趣的列:

SELECT todo_itemStatus.itemStatusId, MAX(todo_itemStatus.statusDate)
FROM todo_item, todo_project, todo_itemStatus 
WHERE todo_item.projectId  = todo_project.projectId 
AND todo_itemStatus.itemId = todo_item.itemId 
AND todo_project.projectId = 13 
GROUP BY itemStatusId

然后我们自动加入这组id以获取我们感兴趣的其余列:

SELECT
    todo_item.itemId, 
    todo_item.title, 
    todo_itemStatus.statusKey, 
    todo_itemStatus.statusDate 
FROM todo_item
JOIN todo_itemStatus
ON todo_itemStatus.itemId = todo_item.itemId 
JOIN
    (SELECT todo_itemStatus.itemStatusId, MAX(todo_itemStatus.statusDate)
    FROM todo_item, todo_project, todo_itemStatus 
    WHERE todo_item.projectId  = todo_project.projectId 
    AND todo_itemStatus.itemId = todo_item.itemId 
    AND todo_project.projectId = 13 
    GROUP BY itemStatusId) AS x
ON todo_itemStatus.itemStatusId = x.itemStatusId

答案 1 :(得分:0)

我已经进行了一些实验,以下查询可以满足我的需求:

select todo_item.itemId, todo_item.title, todo_itemStatus.statusKey, todo_itemStatus.statusDate from todo_itemStatus, todo_item where todo_item.itemId = todo_itemStatus.itemId and todo_item.projectId = 13 and todo_itemStatus.statusDate = (select MAX(status.statusDate) from todo_itemStatus  as status where status.itemId = todo_item.itemId);

所以我现在很高兴。感谢所有的帮助和建议。

戴夫。