MySQL « Быстрый способ сравнения результатов работы двух sql запросов на идентичность

Столкнулся с задачей проверки на идентичность результатов двух запросов. Предполагается, что количество столбцов, их названия идентичны.

Что-то вроде
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }

SELECT purum,pum FROM param WHERE guid=1
 

и
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }

SELECT purum,pum FROM wooo_param WHERE guid=1
 


Как это сделать с помощью языков программирования вопросов не возникает. Можно ли такое осуществить с помощью СУБД MySQL? Интересует лишь TRUE/FALSE, что, где и как там изменилось не суть важно.

1 ответов


Здравствуйте.

Приведенный ниже запрос позволит вам узнать являются ли выборки идентичными. Сначала приведу запрос целиком, а затем пояснения:


SELECT
  IF(t3.cCnt = t3.cCnt2, 1, 0) FROM (
    SELECT COUNT(*) as cCnt, (SELECT COUNT(*) FROM `test_tbl` WHERE `where_field` = 10) as cCnt2 FROM (
      SELECT slct1.* FROM (
        SELECT * FROM `test_tbl` WHERE `where_field` = 10) slct1, (SELECT * FROM `test_tbl2` WHERE `where_field2` = 'search') slct2 WHERE slct1.`id` = slct2.`id`) t2) t3
 

идем из середины:
1. ищем пересечение результатов которые нам надо сравнить

SELECT slct1.* FROM (
        SELECT * FROM `test_tbl` WHERE `where_field` = 10) slct1, (SELECT * FROM `test_tbl2` WHERE `where_field2` = 'search') slct2 WHERE slct1.`id` = slct2.`id`) t2
 
2. считаем количество строк в пересечении и количество строк в одном из запросов. Предполагаем, что идентичные результаты должны иметь в пересечении равное количество строк

SELECT COUNT(*) as cCnt, (SELECT COUNT(*) FROM `test_tbl` WHERE `where_field` = 10) as cCnt2 FROM (
 

3. Если выборки идентичны (количество строк в пересечении совпадает с количеством строк в одном из запросов), то вернуть 1 иначе 0:

SELECT
  IF(t3.cCnt = t3.cCnt2, 1, 0) FROM (
 

примерно так :)

Мне кажется это можно реализовать через NOT EXISTS:
http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html
Еще можно почитать тут: http://www.sql-ex.ru/help/select6.php#traditional


можно и по другому, имхо, просто и понятно, используя LEFT OUTER JOIN с исключением (простое наглядное объяснение http://potapov.com.ua/library/21/#a3):


SELECT *
FROM
(SELECT * FROM param WHERE guid=1) a    # в скобках первый запрос
LEFT OUTER JOIN
(SELECT * FROM param WHERE guid=1) b    # в скобках второй запрос
ON a.pum=b.pum
WHERE b.pum IS NULL;
 
в результате вывода должно быть Empty set , если запросы были действительно одинаковые, в противном случае покажет несовпаднеия из первой таблицы
пример сравнения двух запрсов, с "разными" операторами:


mysql> SELECT *
FROM
(SELECT * FROM mail WHERE srcuser!=dstuser) a   # 1-й запрос
LEFT OUTER JOIN
(SELECT * FROM mail WHERE srcuser<>dstuser) b   # 2-й запрос
ON a.size=b.size
WHERE b.srcuser IS NULL;
Empty set (0.00 sec)
 


SELECT count(wp.pum)
FROM param p LEFT JOIN wooo_param wp
                    ON p.purum=wp.purum
                   AND p.pum=wp.pum
                   AND p.guid=wp.guid
                   AND p.guid=1
                   AND wp.guid IS NULL
 
Результатом будет либо 0, если результаты идентичны, либо отличная от нуля цифра, если - нет в случае, если в левой таблице есть все записи, которые есть в правой, и может быть больше, но не наоборот. Другую часть можно проверить перевернутым запросом.

В Oracle есть оператор MINUS, в некоторых других языках - INTERSECT, EXCEPT.