繁体   English   中英

左联仅带有自我表的第一行

[英]LEFT JOIN with self table only first row

使用MySQL,

我有此活动表,其中包含用户事件:

活动

hash_id | type     | timestamp  | user  |
--------+----------+------------+-------+
abc123  |   ASSIGN | 2015-09-01 | user1 |
456def  |   ASSIGN | 2015-09-02 | user2 |
ghi789  |   ASSIGN | 2015-09-05 | user3 |
012jkl  |   ASSIGN | 2015-09-10 | user4

我希望了解AS的“ ASSIGN”活动的历史,它是何时分配给AS的,以及何时分配AS的,就是分配给其他人的。 (可能还有其他类型的活动,此处将其忽略)

像这样:

start      | end        | user
-----------+------------+-------
2015-09-01 | 2015-09-02 | user1
2015-09-02 | 2015-09-05 | user2
2015-09-05 | 2015-09-10 | user3
2015-09-10 | NA         | user4

对于任何用户N来说,属于另一个用户的将来的ASSIGN事件都意味着对其进行取消分配。

如果对于某个用户N,将来没有“向不同用户的ASSIGN”事件,那么末尾的列可能会显示为“ NA”。 这意味着当前已分配了userN。

因此,我认为解决方案可能来自于活动表本身的左联接。 但是目前,我只能获得一些令人困惑的活动历史记录,以及用户的每个时间戳记以及表上的其他所有活动。

我越来越:

start      | end        | user
-----------+------------+-------
2015-09-01 | 2015-09-02 | user1
2015-09-01 | 2015-09-05 | user1
2015-09-01 | 2015-09-10 | user1
2015-09-02 | 2015-09-05 | user2
2015-09-02 | 2015-09-10 | user2
2015-09-05 | 2015-09-10 | user3
2015-09-10 | NA         | user4

我注意到,JOIN正在检索活动与将来活动之间的所有关系,实际上,如果我可以检索JOIN的第一个结果,则可以解决此问题。 这就是我遇到的问题。

我目前在玩两个可能的查询,都向我抛出相同的结果:

这是我的第一次尝试:

   SELECT a.timestamp AS start,
          COALESCE(endac.timestamp,'NA') AS end,
          a.user
     FROM activity a
LEFT JOIN 
          (SELECT ac.timestamp, ac.groupkey, ac.assigneduserkey, ac.type
             FROM activity jac
            WHERE jac.type='ASSIGN'
          ) endac
       ON (endac.user <> a.user AND endac.timestamp > a.timestamp)
    WHERE a.type = 'ASSIGN'

这另一条来自我在LEFT JOIN上读的第一行

   SELECT a.timestamp AS start,
          COALESCE(endac.timestamp,'NA') AS end,
          a.user
     FROM activity a
LEFT JOIN activity endac
       ON (endac.hash_id = (SELECT jact.hash_id
                              FROM activity jact
                             WHERE jact.hash_id=endac.hash_id
                               AND jact.type = 'ASSIGN'
                               AND jact.user <> a.user
                               AND jact.timestamp > a.timestamp
                             LIMIT 1
                           )
          )
    WHERE a.type = 'ASSIGN'

有什么建议么? 我是否在正确的道路上满足我的需求? 如何只获得JOIN的第一行,以便获得正确的结果?

这应该不太复杂!

SELECT
  plus.timestamp AS start,
  IFNULL(MIN(minus.timestamp),'NA') AS end,
  plus.user AS user
FROM
  activity AS plus
  LEFT JOIN activity AS minus
    ON minus.timestamp>plus.timestamp
GROUP BY plus.timestamp
ORDER BY plus.timestamp
;

给出了预期的输出,但是效率很低。

SQLfiddle

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM