Jump to content

Recommended Posts

I am doing a versioning system so that every time you edit a page, the old page is still kept but the new page is shown insted. I have that working find but when I am trying to list the pages I am having problems getting a query to do it.

I have a table like this:
[code]CREATE TABLE `pages` (
  `id` varchar(25) NOT NULL default '',
  `date` datetime NOT NULL default '0000-00-00 00:00:00',
  `title` varchar(25) NOT NULL default '',
  `content` mediumtext NOT NULL,
  PRIMARY KEY  (`id`,`date`),
  FULLTEXT KEY `Search` (`title`,`content`)
);[/code]
I want to count all of the ID's with the most recent date. I have tried:
[code]SELECT COUNT(*) as total FROM pages GROUP BY date HAVING MAX(date)[/code]
returns 0
[code]SELECT COUNT(MAX(date)) FROM pages GROUP BY date[/code]
but that returns this error
[code]#1111 - Invalid use of group function[/code]

Does anyone know of a solution?
Link to comment
https://forums.phpfreaks.com/topic/3842-max-problem/
Share on other sites

Not possible to use MAX() the way you want without a subquery. Fenway's is easy but causes a potentially very slow table scan. Also, I'm assuming you would rather group by day, not by second? Grouping the pages updated in the same second doesn't seem useful.

Here's two solutions for grouping on the most recent day:
[code]SELECT COUNT(*) as total, DATE(date) as justdate FROM pages GROUP BY justdate ORDER BY justdate DESC LIMIT 1[/code]
That one will be just as slow as fenway's. This one will run a lot faster though:
[code]SELECT COUNT(*) as total FROM pages a
INNER JOIN (SELECT DATE(MAX(date)) as justdate FROM pages) b
   ON a.date BETWEEN CAST(b.justdate as DATETIME)
   AND CAST(b.justdate + INTERVAL 1 DAY as DATETIME)[/code]
Link to comment
https://forums.phpfreaks.com/topic/3842-max-problem/#findComment-13384
Share on other sites

That would be much better; use the following:

[code]SELECT COUNT( DISTINCT id ) FROM pages[/code]

Which is very well optimized by MySQL.

BTW, regarding wickning1's comment, I simply assumed that this column was indexed. If not, well, yeah, table scan is guaranteed; same goes doing such a sort on any part of date (e.g. using the DATE() function). In that case, you have do use a join to get around this problem, as wickning1 suggested.
Link to comment
https://forums.phpfreaks.com/topic/3842-max-problem/#findComment-13462
Share on other sites

Nope, even with an index, I'm 90% certain that that subquery you wrote will table scan. Ideally it shouldn't, but I know from experience, in 5.0, it still does. The parsing engine can't be absolutely sure that the subquery will be the same for every row, so it assumes that it won't be.

In general, avoid putting subqueries in the WHERE clause. Put them in the FROM clause instead, where the statement will only be evaluated once.
Link to comment
https://forums.phpfreaks.com/topic/3842-max-problem/#findComment-13473
Share on other sites

I disagree; first, only correlated sub-queries are run every time -- the optimizer takes care of non-correlated ones automatically. I tried it with an index of the date column in 4.1:

[code]EXPLAIN SELECT COUNT(*) as total FROM pages WHERE theDate = ( SELECT MAX(theDate) FROM pages )

+----+-------------+--------+--------+---------------+---------+---------+--------+--------+------------------------------+
| id | select_type | table  | type   | possible_keys | key     | key_len | ref    | rows   | Extra                        |
+----+-------------+--------+--------+---------------+---------+---------+--------+--------+------------------------------+
|  1 | PRIMARY     | pages  | ref    | theDate       | theDate |       3 | const  |      1 | Using where; Using index     |
|  2 | SUBQUERY    | [NULL] | [NULL] | [NULL]        | [NULL]  |  [NULL] | [NULL] | [NULL] | Select tables optimized away |
+----+-------------+--------+--------+---------------+---------+---------+--------+--------+------------------------------+[/code]

Just thought you might be interested.
Link to comment
https://forums.phpfreaks.com/topic/3842-max-problem/#findComment-13566
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.