我一直试图解决这个问题,但没有运气,所以如果有人可以帮助我,那就太好了。
我有两张桌子。物品和物品标志。
物品
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显然不起作用。所以我们提出了一个不同的解决方案,我正在运行测试,我会尽快发布,以防它可能对其他人有用。
答案 0 :(得分:1)
您可以使用以下GROUP BY
GROUP BY
items.id,
items.name,
items.levelid,
items.containertypeid,
items.roomid,
items.userid
由于items.id是唯一的,因此会将记录分组为“GROUP BY items.id”。
对于数据库来说,这似乎更有用,但是由数据库决定它只能检查分组的ID。
答案 1 :(得分: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 here。
可替换地:
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 here。
答案 2 :(得分:-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