Reputation: 4146
I'm looking for a mysql query (using php) to go through each table one at a time and only display results that are different than those in cross_check.lastmod
t_one
guid | name | lastmod
1 | Joe | 2012-01-01 01:00:00
2 | Tom | 2012-01-02 01:00:00
3 | Sue | 2012-03-01 02:00:00
t_two
guid | pet | lastmod
4 | cat | 2012-01-01 01:00:00
5 | dog | 2012-01-02 01:00:00
6 | fish | 2012-03-01 02:00:00
t_three
guid | fruit | lastmod
7 | orange | 2012-01-01 01:00:00
8 | pear | 2012-01-02 01:00:00
9 | grape | 2012-03-01 02:00:00
cross_check
guid | lastmod
1 | 2012-01-01 01:00:00
2 | 2012-01-02 01:00:00
3 | 2012-01-01 02:00:00
4 | 2012-01-01 01:00:00
5 | 2012-01-02 01:00:00
6 | 2012-01-01 02:00:00
7 | 2012-01-01 01:00:00
8 | 2012-01-02 01:00:00
9 | 2012-01-01 02:00:00
The query results would be:
t_one => 3 | Sue | 2012-03-01 02:00:00
t_two => 6 | fish | 2012-03-01 02:00:00
t_three => 9 | grape | 2012-03-01 02:00:00
My code so far (needs the table cross reference)
$tables = array('t_one', 't_two', 't_three');
foreach ($tables AS $table) {
$query = sprintf("SELECT * FROM '%s'",
mysql_real_escape_string($table));
$result = mysql_query($query);
}
Upvotes: 0
Views: 1016
Reputation: 56935
Just JOIN
in the cross_check
table.
SELECT t_one.*
FROM t_one
JOIN cross_check ON t_one.guid=cross_check.guid
WHERE t_one.lastmod != cross_check.lastmod
Still one query per table, though (you can fart around with unions but that doesn't reduce the core number of queries).
If you wanted to combine them into one, you could use UNIONs:
[query for t_one]
UNION
[query for t_two]
UNION
[query for t_three]
I feel like this isn't all that more efficient than doing three different queries (a gut feel though, unsubstantiated claim).
You could also do (although this only works if there's no crossover between the t_*
guid
s; if there is t_one
will be favoured, then t_two
):
SELECT COALESCE(t_one.guid,t_two.guid,t_three.guid) AS guid
FROM cross_check
LEFT JOIN t_one ON t_one.guid=cross_check.guid
LEFT JOIN t_two ON t_two.guid=cross_check.guid
LEFT JOIN t_three ON t_three.guid=cross_check.guid
WHERE (t_one.lastmod IS NOT NULL AND t_one.lastmod != cross_check.lastmod)
OR (t_two.lastmod IS NOT NULL AND t_two.lastmod != cross_check.lastmod)
OR (t_three.lastmod IS NOT NULL AND t_three.lastmod != cross_check.lastmod)
You could also put COALESCE(t_one.name, t_two.pet, t_three.fruit) AS label
if you wanted to grab the labels as opposed to the ids.
Upvotes: 4
Reputation: 1185
Try using this query, replacing of course, the table name in the foreach loop.
SELECT origin.guid as guid FROM t_one as origin, cross_check as cross WHERE cross.lastmod != origin.lastmod;
Upvotes: 0