简体   繁体   中英

MySQL query cross reference

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);

  }

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.

尝试使用此查询,当然替换为foreach循环中的表名。

SELECT origin.guid as guid FROM t_one as origin, cross_check as cross WHERE cross.lastmod != origin.lastmod;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM