2011-09-20 23 views
1

我有下表。Zend DB从同一表中加入2行

--------------------------------------------- 
check_id | action_id | user_id |   dt | 
--------------------------------------------- 
     1 |   1 |  6 | 2011-09-17 | 
     2 |   1 |  6 | 2011-09-18 | 
     3 |   3 |  6 | 2011-09-19 | 
     4 |   3 |  6 | 2011-09-20 | 
--------------------------------------------- 

我想查询此表并获得以下结果。

----------------------------------------------- 
action_id | user_id | dt_start |  dt_end | 
----------------------------------------------- 
     1 |  6 | 2011-09-17 | 2011-09-18 | 
     3 |  6 | 2011-09-19 | 2011-09-20 | 
----------------------------------------------- 

所以我使用下面的查询。

​​

但是,这给了我以下结果。

----------------------------------------------- 
action_id | user_id | dt_start |  dt_end | 
----------------------------------------------- 
     1 |  1 | 2011-09-17 | 2011-09-17 | 
     1 |  3 | 2011-09-19 | 2011-09-19 | 
----------------------------------------------- 

有人能告诉我我做错了什么吗?

+1

目前还不清楚您尝试通过Zend_Db_Select创建什么SQL。你可以将SQL添加到问题中吗?另外,您可以使用Zend_Db_Select :: toString方法来打印查询时将执行的SQL,这可能会帮助您进行调试。 –

回答

1

通过尝试此查询,且不包括群组:

SELECT * 
FROM checks c1 LEFT OUTER JOIN checks c2 ON c1.action_id = c2.action_id 
WHERE c1.user_d = 6 

你会看到,你在那里c1.dt < c2.dt,这是你想要的比赛。 但你也可以在c1.dt> c2.dt和c1.dt = c2.dt处找到匹配项。 也就是说,自联接包含结果,其中c1和c2指向相同的行。

然后,您使用GROUP BY将多行合并为一个,但MySQL从该组中选择任意行。 (这是一个模糊的查询,如果您SET SQL_MODE='ONLY_FULL_GROUP_BY'你会得到一个错误。)

那么你的自我加入和GROUP BY 只有返回C1和C2这实际上是非常同一行。

要解决这个问题,您应该添加一个条件,即c1.dt < c2.dt.

$checks->select() 
->from(array('c1' => 'checks'), array('dt as dt_start') 
->joinLeft(array('c2' => 'checks'), 
      'c1.action_id = c2.action_id AND c1.dt < c2.dt', 
      array('dt as dt_end') 
->where('c1.user_id = ?', $userId) 

在这种情况下,您可能根本不需要GROUP BY,假设您没有多个开始和结束的每个操作。

顺便说一句,这种类型的复杂性是通常建议将事件开始/结束数据存储在单行中的一个原因,其中起始于一列,结束于第二列。

+0

使用GROUP BY action_id给我我需要的结果。我也可以使用joinRight,但这也只给我一行结果。当两行共享相同的action_id时,我需要结果。也许将开始日期和结束日期存储在一行中是更好的解决方案。我正在建立一个入住/退房系统。 – Stuiterbal

+0

右连接不会返回action_id尚未与另一行共享的行。我也需要这些。所以一个LEFT JOIN和一个GROUP BY结合起来就可以做到这一点。 – Stuiterbal

+0

这很好,但是您是否获得了关于测试fot c1.dt