2

我一直在努力解决这个问题,但没有运气,所以如果有人可以帮助我,那就太好了。

我有2张桌子。项目和项目标志。

物品

id        name       levelid        containertypeid        roomid        userid      timestamp
--        ----       -------        ---------------        ------        ------      -----
1         Item 1     0              0                      3             5           1365072108
2         Item 2     0              0                      3             5           1365342108
3         Item 3     0              0                      3             5           1389072108
4         Item 4     0              0                      3             5           1365085108
5         Item 5     2              3                      3             5           1365962108
6         Item 6     1              3                      3             5           1365322108

Item_Flags

id        itemid     flagid        userid        timestamp
--        ----       -------       -------       ---------
1         1          1              5            1365072108
2         1          5              5            1365342108
3         1          2              5            1389072108
4         1          3              5            1365085108
5         2          4              5            1365762108
6         2          1              5            1365921087
7         2          3              5            1365252108
8         3          6              5            1365982108
9         3          7              5            1365312108
10        3          8              5            1365342108

目标

我要做的是获取所有项目的列表,按降序时间戳排序。因此,实际上,我想要一个基于我们更新实际项目或为项目添加标志的最新时间戳的项目列表。每次针对特定项目添加标志或更新项目名称或级别时,应用程序都会更新时间戳。问题是如果我想取回名称、levelid 等字段,我无法运行 GROUP BY,因为我在聚合函数中使用了它们,所以实际值不会回来。如果我不将它们分组,我显然会为每个项目获得多个结果,具体取决于它有多少个标志。这是我的查询:

SELECT 
                items.id,
                items.name,   
                items.levelid,
                items.containertypeid,
                items.roomid,
                items.userid
        FROM 
                items
        LEFT OUTER JOIN item_flags ON
                items.id = flags.itemid
        WHERE
                items.levelid = 0 AND 
                items.containertypeid = 0 AND 
                items.room = 3 AND
                items.userid = 5
        GROUP BY 
               items.id
        ORDER BY 
               items.timemodified DESC
               item_flags.timemodified DESC

如果我将除 items.id 之外的所有选择字段包装在聚合函数中并完全删除 ORDER ,我可以让它工作,但是当我取回它们时我需要使用这些字段并且我需要它们!在这一点上,我什至不确定查询中的逻辑是否有意义,因为虽然我说 flags.itemid 等于 items.id,但那里存在一对多的关系。

我看过SQL Query - Grouping with multiple tables,但那里没有 ORDER BY ,我不知道如何使它工作!

使用 PG SQL。

谢谢!

====================================

事实证明,最后,查询也必须与 MySQL 一起使用,而 With 显然不起作用。所以我们提出了一个不同的解决方案,我正在运行测试,我会尽快发布,以防它可能对其他人有用。

4

3 回答 3

1

您可以使用以下 GROUP BY

GROUP BY
            items.id,
            items.name,   
            items.levelid,
            items.containertypeid,
            items.roomid,
            items.userid

由于 items.id 是唯一的,这会将记录分组为“GROUP BY items.id”。

对于数据库来说,这似乎需要做更多的工作,但由数据库决定它可以只检查分组的 id。

于 2013-04-18T16:03:09.350 回答
1

一种方法:

with cte as
(SELECT id,
        timestamp,
        name,   
        levelid,
        containertypeid,
        roomid,
        userid
 FROM items
 UNION ALL
 SELECT itemid id,
        timestamp,
        NULL as name,
        NULL as levelid,
        NULL as containertypeid,
        NULL as roomid,
        NULL as userid
 from item_flags)
select id,
       max(timestamp) as timestamp,
       max(name) as name,   
       max(levelid) as levelid,
       max(containertypeid) as containertypeid,
       max(roomid) as roomid,
       max(userid) as userid
from cte
group by id
order by 2 desc

SQLFiddle在这里

或者:

select id,
       max(timestamp) as timestamp,
       max(name) as name,   
       max(levelid) as levelid,
       max(containertypeid) as containertypeid,
       max(roomid) as roomid,
       max(userid) as userid
from 
(SELECT id,
        timestamp,
        name,   
        levelid,
        containertypeid,
        roomid,
        userid
 FROM items
 UNION ALL
 SELECT itemid id,
        timestamp,
        NULL as name,
        NULL as levelid,
        NULL as containertypeid,
        NULL as roomid,
        NULL as userid
 from item_flags) sq
group by id
order by 2 desc

SQLFiddle在这里

于 2013-04-18T16:17:42.373 回答
-1

所以最后,我们已经解决了这个问题:

SELECT 
items.id, 
max(items.name) as name,
max(item_flags.flagid) as flagid,
max(COALESCE(item_flags.timestamp, items.timestamp)) AS tm
FROM   
items
LEFT JOIN 
item_flags 
ON 
item_flags.itemid = items.id 
GROUP BY items.id 
ORDER BY tm DESC
于 2013-04-22T13:29:29.843 回答