Okay, we have a database, with a not-so-good tables-columns layout, for a small news agency functioning online. Changing the layout is, currently, not possible; so, I’m focused on the queries.
Webpage requires a list of “guest” authors. Each list item should contain:
- Author’s image (Authors)
- Author’s name (Authors)
- Title of the last article he/she wrote (News)
- URI of that article (News)
In parentheses are the table names that info is stored in.
In “Authors” (40+ records), relevant columns are:
- Image
- Name
- Type (we’ll look for the value “Guest” here)
- ASCII (stores the “Name” value but without non-English characters and spaces)
The “News” (28k+ records) table is, basically, a pool where all the news and articles are pouring in. Columns of interest would be:
- Id (primary key: the higher, the more recent)
- Category
- Title
- URI
Now, “Category” has a whole bunch of values; however, if the particular record is an article, this column holds the “ASCII” of “Authors” (rather than its “Id”, sadly).
There was a PHP code, “while”ing queries for each author. I wanted to replace that when I saw it. So, I thought, “Hmm… How to fetch these in one go?” and came up with this:
-- Aliases are prefixed with 't' for tables and 'c' for columns.
SELECT
tAu.Image, tAu.Name, tNw.Title, tNw.URI
FROM ( -- tAu & tNw
SELECT * FROM ( -- tRc & Authors
SELECT
MAX(Id) cId, Category cCt -- Max Id for most recent
FROM
News
GROUP BY
cCt
) tRc -- table of categories with their most recent id's
INNER JOIN
Authors
ON
tRc.cCt = Authors.ASCII
WHERE
Authors.Type = 'Guest'
) tAu -- table of authors with their most recent id's
INNER JOIN
News tNw
ON
tAu.cId = tNw.Id -- merging authors with their latest article info
Currently, this query takes around 0.0364 seconds. May not be that bad; but, I am curious if this can be made any better (as this query SELECTs twice from News).
I don’t know if it is faster or not, but cleaned up your query a bit, which may help the optimizer:
Newstable should have an index starting with( Category, Id)to speed up the internalSELECT GROUP BY.