简体   繁体   English

SQL每个ID仅选择一次,按最早的日期时间选择

[英]SQL Select only once of each id, chosen by earliest datetime

I'm currently having to run a query like the below for a one off report process at work. 我目前必须运行类似下面的查询,以便在工作中进行一次性报告。

However for each item in the table there are multiple associated "messages" that are all saved, this means each item is returned multiple times. 但是,对于表中的每个项目,都会保存多个关联的“消息”,这意味着每个项目都会被多次返回。 I'd like to only show each item once, as per the examples and further explanation below. 根据下面的示例和进一步的说明,我只希望每个项目显示一次。

I realize this is (at least in my opinion) a poor structure, but the report needs to be done and this is how the data is stored :-( 我意识到这(至少在我看来)是一个糟糕的结构,但是需要完成报告,这就是存储数据的方式:-(

SQL Fiddle: http://sqlfiddle.com/#!6/76fce/8 SQL小提琴: http ://sqlfiddle.com/#!6 / 76fce / 8

Query: 查询:

SELECT messageId, receiver, createdDate, itemId from messages_0,items WHERE
    itemId IN (1, 2, 3)
    AND (receiver = '100' OR receiver = '200')
    AND messages_0.description LIKE '%'+items.name+'%'
union all
SELECT messageId, receiver, createdDate, itemId  from messages_1,items WHERE
    itemId IN (1, 2, 3)
    AND (receiver = '100' OR receiver = '200')
    AND messages_1.description LIKE '%'+items.name+'%'

Note: there are two message tables, hence the union all 注意:有两个消息表,因此将所有

Example messages: 消息示例:

messageId | receiver | createdDate       | description
--------------
1         | 100      | 2012/11/27 12:00  | The Dog is awesome
2         | 100      | 2012/11/27 13:00  | Now the Dog is boring
4         | 200      | 2012/11/27 11:30  | I have Wood :-)

Example items: 示例项目:

itemID | name 
--------------
1      | Dave
2      | Dog
3      | Wood

Result: 结果:

messageId | receiver | createdDate      | itemId 
1         | 100      | 2012/11/27 12:00 | 2
2         | 100      | 2012/11/27 13:00 | 2
4         | 200      | 2012/11/27 11:00 | 3

However, I need to only show each item once. 但是,我只需要显示一次即可。 Where only the oldest row (by the createdDate) is shown. 仅显示最旧的行 (由createdDate列出)。

Target Result: 目标结果:

messageId | receiver | createdDate      | itemId 
1         | 100      | 2012/11/27 12:00 | 2
4         | 200      | 2012/11/27 11:00 | 3

How can I do this in SQL (Sybase)? 如何在SQL(Sybase)中执行此操作? So far I have been looking at both group by (which would only return an id) and some sort of sub query, but have been unable to get anything to work! 到目前为止,我一直在研究group by(只会返回一个id)和某种子查询,但是一直无法使任何事情起作用!

SQL Fiddle: http://sqlfiddle.com/#!6/76fce/8 SQL小提琴: http ://sqlfiddle.com/#!6 / 76fce / 8

If I understood you right, something like this could be a start. 如果我理解正确,那么可能是一个开始。

SELECT
  t, messageId, receiver, createdDate, itemId 
FROM
  (
    SELECT 
      m.messageId, m.receiver, m.createdDate, m.t,
      i.itemId 
    FROM
      items i
      INNER JOIN (
        SELECT description, messageId, receiver, createdDate, 0 t FROM messages_0 
        UNION 
        SELECT description, messageId, receiver, createdDate, 1 t FROM messages_1
      ) m ON m.description LIKE '%' + i.name + '%' 
             AND m.receiver IN ('100', '200')
    WHERE
      i.itemId IN (1, 2, 3)
  ) data
WHERE
  createdDate = (
    SELECT MIN(createdDate) FROM (
      SELECT createdDate FROM messages_0 WHERE messageId = data.messageId AND data.t = 0
      UNION
      SELECT createdDate FROM messages_1 WHERE messageId = data.messageId AND data.t = 1
    )
  )

I would put indexes on 我会把索引放在

  • messages_0 / messages_1 messages_0 / messages_1
    • (messageId, createdDate) (messageId,createdDate)
    • (receiver, messageId, createdDate, description) (接收者,messageId,createdDate,描述)
  • items 项目
    • (itemId, name) (itemId,名称)

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

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