Обсуждение: Aggregates
Hi, If I have a table with users and a table with messages, is it possible to have a query that returns user.* as well as one extra column with the number of messages they have posted and the data and time of the last message? At the moment I am using a subquery to do this, however it seems suboptimal. Is there a better way? - Naz.
Naz Gassiep wrote: > Hi, > If I have a table with users and a table with messages, is it > possible to have a query that returns user.* as well as one extra column > with the number of messages they have posted and the data and time of > the last message? At the moment I am using a subquery to do this, > however it seems suboptimal. Is there a better way? Not really. You have three separate queries really: 1. User details 2. Total number of messages posted 3. Details on last message posted Unless you have a messaging-summary table that you keep up-to-date with triggers you're looking at a three-part query. -- Richard Huxton Archonet Ltd
On Jun 21, 2007, at 09:22, Richard Huxton wrote: > Naz Gassiep wrote: >> Hi, >> If I have a table with users and a table with messages, is it >> possible to have a query that returns user.* as well as one extra >> column >> with the number of messages they have posted and the data and time of >> the last message? At the moment I am using a subquery to do this, >> however it seems suboptimal. Is there a better way? > > Not really. You have three separate queries really: > 1. User details > 2. Total number of messages posted > 3. Details on last message posted > > Unless you have a messaging-summary table that you keep up-to-date > with triggers you're looking at a three-part query. Certainly except for the user details it could be a single GROUP BY with several aggregate functions, something like: select user.userid, count(*), max(message.datetime) from user join message using (userid) group by user.userid; But if userid is UNIQUE, then so is user.*. You can't do something like GROUP BY USER.*, but you can group by all the user columns you're actually interested in selecting: select userid, user.name, user.address, count(*), max (message.datetime) from user join message using (userid) group by userid, user.name, user.address; As to whether this is faster or prettier than a subquery, I dunno. - John D. Burger MITRE
John D. Burger wrote: > > On Jun 21, 2007, at 09:22, Richard Huxton wrote: > >> Naz Gassiep wrote: >>> Hi, >>> If I have a table with users and a table with messages, is it >>> possible to have a query that returns user.* as well as one extra column >>> with the number of messages they have posted and the data and time of >>> the last message? At the moment I am using a subquery to do this, >>> however it seems suboptimal. Is there a better way? >> >> Not really. You have three separate queries really: >> 1. User details >> 2. Total number of messages posted >> 3. Details on last message posted >> >> Unless you have a messaging-summary table that you keep up-to-date >> with triggers you're looking at a three-part query. > > Certainly except for the user details it could be a single GROUP BY with > several aggregate functions, something like: > > select user.userid, count(*), max(message.datetime) > from user join message using (userid) > group by user.userid; Ah, but this just includes the time of the last message, not its data. -- Richard Huxton Archonet Ltd
Richard Huxton wrote: > Ah, but this just includes the time of the last message, not its data. Oops, I read the OP's question as "date and time", rather than "data and time". Nevermind. :) - John D. Burger MITRE