Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2011, 10:36   #1
parashutist
 
Регистрация: 23.05.2010
Сообщений: 3
По умолчанию Сравнение таблиц

Необходимо сравнивать две практически идентичные таблицы, и находить в них записи, которых нет в другой таблице. То есть записи которые не дублируются в обоих таблицах.
Есть вариант использовать left join ...on... where tabl1.id is null. Вариант как бы работает, но не совсем корректно, потому как записи в таблицах могут повторятся. Например: назовем запись record1, так вот, она может в одном файле встретится 2 раза, а во втором 3, и нам необходимо отследить, что она один раз потерялась в одном из файлов. Вышеописанный способ её не выведет.
Придумал вариант с удалением. select from table1 одну запись - delete from table2 эту же запись. Если удаление успешное (запись присутствует во второй таблице) то delete from table1 такую же запись.
Такой вариант работает корректно, но ужасно долго. На каждую запись 3 запроса.. и если в файлах по 100 000 записей, что для моей задачи не много, скрипт работает порядка 4 минут... Может кто-то знает как это дело сделать одним запросом?
parashutist вне форума Ответить с цитированием
Старый 02.08.2011, 10:45   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
так вот, она может в одном файле встретится 2 раза, а во втором 3, и нам необходимо отследить, что она один раз потерялась в одном из файлов.
Это как?
Вы записи по ID сравниваете? Как вообще может быть 2 (тем более 3) записи с одинаковым ID ?!
приведите пример данных - можно прямо в тексте сообщения - что Вы имеете в таблицах и что хотите получить в итоге.

p.s. сдаётся мне, что странного хотите, поэтому и проблемы возникают...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.08.2011, 10:57   #3
parashutist
 
Регистрация: 23.05.2010
Сообщений: 3
По умолчанию

Нет, конечно же не по id. Сравниваю по 3м полям: cli, cld, connect_time
Пример структуры таблиц:
+-----+---------+---------+--------------+--------------+----------------+
| id | cli | cld | connect_time | charged_time | charged_amount |
+-----+---------+---------+--------------+--------------+----------------+
| 832 | 4284462 | 2566700 | 1309437268 | 00:00:42 | 0.02934 |
| 833 | 7205008 | 4507247 | 1309437156 | 00:03:16 | 0.02198 |
+-----+---------+---------+--------------+--------------+----------------+
parashutist вне форума Ответить с цитированием
Старый 02.08.2011, 11:22   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

дайте пример, что находится в одной таблице, что во второй (с Вашими повторами)
и приведите пример, что Вы хотите получить в итоге...


Кстати, Вы хотите просто получить результат запроса или удалять записи из какой-то из таблиц?!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.08.2011, 13:35   #5
parashutist
 
Регистрация: 23.05.2010
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
дайте пример, что находится в одной таблице, что во второй (с Вашими повторами)
и приведите пример, что Вы хотите получить в итоге...
Ну вот упрощенный пример.
Таблица 1:
+----+---------+---------+--------------+--------------+----------------+
| id | cli | cld | connect_time | charged_time | charged_amount |
+----+---------+---------+--------------+--------------+----------------+
| 1 | 4104083 | 4640119 | 1312317142 | 00:00:00 | 0 |
| 2 | 3104124 | 5639697 | 1312317203 | 00:03:46 | 0.21734 |
| 3 | 9724944 | 2744773 | 1312317169 | 00:00:00 | 0 |
| 4 | 3777855 | 5467864 | 1309635109 | 00:00:00 | 1.25541 |
+----+---------+---------+--------------+--------------+----------------+

Таблица 2:
+----+---------+---------+--------------+--------------+----------------+
| id | cli | cld | connect_time | charged_time | charged_amount |
+----+---------+---------+--------------+--------------+----------------+
| 2 | 3104124 | 5639697 | 1312317203 | 00:03:46 | 0.21734 |
| 1 | 4104083 | 4640119 | 1312317142 | 00:00:00 | 0 |
| 4 | 4104083 | 4640119 | 1312317142 | 00:00:00 | 0 |
| 3 | 9724944 | 2744773 | 1312317169 | 00:00:00 | 0 |
+----+---------+---------+--------------+--------------+----------------+

В данном случае правильным для нас результатом будет вывод двух записей:

| 3777855 | 5467864 | 1309635109 | 00:00:00 | 1.25541 |
| 4104083 | 4640119 | 1312317142 | 00:00:00 | 0 |

id нам не важен.

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Кстати, Вы хотите просто получить результат запроса или удалять записи из какой-то из таблиц?!
Мне в данном случае не важна дальнейшая судьба таблиц, нужно только получить информацию.
parashutist вне форума Ответить с цитированием
Старый 02.08.2011, 15:24   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

1) какая у Вас СУБД ?

2) я бы решал эту задачу так:

a) откинул поля charged_time, charged_amount
они не нужны при сравнении, а значит от них будет только лишняя морока + возможные проблемы (если интересно почему - расскажу, сейчас не будем на этом циклиться

b) разделил все записи, которые нам нужны на три группы:
группа A. записи, которые есть в таблице 1 и их нет в таблице 2
группа B. записи, которые есть в таблице 2 и их нет в таблице 1
группа C записи, которые есть в обоих таблицах, но их количество не совпадает.

дальше нарисовал запрос с тремя UNION'ами
очевидно, что первые два селекта для выбора групп A и B - элементарные, а вот с третьим прийдётся повозиться.
для реализации третьего подзапроса (группа C) я бы сделал группировку по нужным полям и выбрал поле count(*), ну и выбирал записи где ключевые поля совпадают, а эти count(*) - отличаются...
правда, если в таблице 1 есть (допустим):
| 1 | 4104083 | 4640119 | 1312317142 |
| 2 | 4104083 | 4640119 | 1312317142 |
| 3 | 4104083 | 4640119 | 1312317142 |
| 4 | 4104083 | 4640119 | 1312317142 |

а в таблице 2
|99| 4104083 | 4640119 | 1312317142 |

тогда по моему алгоритму в итоговой выборке окажется одна запись
Код:
+---------+---------+--------------+----------+
| cli     | cld     | connect_time |  CntRec  |
+---------+---------+--------------+----------+
| 4104083 | 4640119 | 1312317142   |  3       |
+---------+---------+--------------+----------+
3 это разница между количеством 4 и 1

Но, если Вам нужно три одинаковых строчки - то прийдётся проходить в цикле по таким записям и добавлять нужное число строк...
А если устроит и такой вариант - тогда дополнительных телодвижений не потребуется - один сложный запрос и вуаля... готов результат!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 11.02.2012, 14:46   #7
kg2
Новичок
Джуниор
 
Регистрация: 11.02.2012
Сообщений: 1
По умолчанию

Serge_Bliznykov как можно запросом выбрать записи, которые есть в таблице 1 и их нет в таблице 2
kg2 вне форума Ответить с цитированием
Старый 11.02.2012, 16:14   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

kg2,
без конкретики (что за поля, как связаны, какая СУБД)?!...


ну, например, так:
Код:
select * from Таблица1 
  where КлючевоеПоле not in 
      (select Таблица2.КлючевоеПоле from Таблица2 )

p.s. а чего Вы новую тему не создали, зачем в чужой писать?
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сравнение таблиц Artemius01 Microsoft Office Excel 5 04.04.2011 12:05
сравнение двух таблиц Iskin Microsoft Office Excel 3 08.12.2010 07:18
сравнение таблиц fox2la Microsoft Office Excel 7 27.10.2010 16:04
Сравнение значениний двух таблиц azz123 Microsoft Office Excel 2 06.11.2009 10:54
Сравнение двух таблиц scaramangi Microsoft Office Excel 0 17.09.2009 17:15