子句

时间:2017-01-15 21:57:25

标签: sql sqlite

一个包含4个主要列的表message

  • id:消息的ID。
  • interlocutor_id:对话者的身份。
  • timestamp:邮件发送的时间戳。
  • expiration:邮件过期的时间戳。如果该值低于当前时间戳,则该值已过期。

我希望获取每个对话者的所有最后消息(即使它们已过期),并且我也希望所有未过期的消息(即使它们不是最后的消息)。

我尝试了此查询,但后来我明白我无法创建包含多个列的子查询:

SELECT * FROM message 
WHERE  (expiration > 'CURRENT_TIMESTAMP') 
OR  (id IN (SELECT id, MAX(timestamp) FROM message GROUP BY interlocutor_id) )

我该怎么办?

2 个答案:

答案 0 :(得分:1)

这样做的一种方法是加入子查询。创建一个子查询,返回每个interlocutor_id的最大日期,然后将其加入。

SELECT M.* 
FROM message M
LEFT JOIN
    (SELECT interlocutor_id, MAX(timestamp) ts FROM message GROUP BY interlocutor_id) LastTime 
    on LastTime.interlocutor_id = M.interlocutor_id AND m.timestamp = Lasttime.ts
WHERE  (expiration > 'CURRENT_TIMESTAMP') 
OR  LastTime.id is not null

或者,您可能希望查看EXISTS而不是Join来查看子查询,具体取决于您的数据,这可能会更好。

答案 1 :(得分:1)

我认为这是你想要的:

class Widget {

    private final String       name;
    private final WidgetType[] widgetTypes;

    Widget(String n, WidgetType ... wt) { name = n; widgetTypes = wt; }

    public String getName() { return name; }
    public Stream<WidgetType> getWidgetTypes() { return Arrays.stream(widgetTypes).distinct(); }

    @Override public String toString() { return name; }
}

enum WidgetType { TYPE_A, TYPE_B, TYPE_C, TYPE_D }

另外,当您说SELECT m.* FROM message m WHERE (m.expiration > 'CURRENT_TIMESTAMP') OR m.timestamp = (SELECT MAX(timestamp) FROM message m2 WHERE m2.interlocutor_id = m.interlocutor_id ); 时,您的意思是'CURRENT_TIMESTAMP'