Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Привет всем!

Возник вопрос - как определить разницу в данных между двумя записями в таблице?
Например
PKNAMECODE
1GeorgeGG
2GeorgyGG

В результате хотелось бы получить в каком-то виде, что изменилось значение колонки NAME c George на Georgy. Ессно ситуация интересна, когда в таблице скажем 2 десятка колонок.
Лучший вариант - строка из серии 'NAME George Georgy'.

Спасибо за внимание
6 фев 14, 00:08    [15525744]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
aleks2
Guest
self join +nillif()

А колонки не надо лениться писать.
6 фев 14, 07:48    [15526069]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
как определить разницу в данных между двумя записями в таблице?

Т.е. у вас в таблице строго 2 записи что ли ?
6 фев 14, 10:19    [15526745]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory,

нет конечно :) Записей может быть и мульен. Стоит задача - сравнить две заданные строки. Забыл уточнить - что колонка PK - это собственно первичный ключ. И сравнение нужно производить по двум заданным значениям первичного ключа.

По просьбе выше - приведу бОльшую табличку

PK NAME CODE DINPUT VDIR VFILE
1 George GG 01/02/2014 D:\GG\SelfPath gg.cfg
2 Georgy GG 03/02/2014 D:\GG\SelfPath gg.cfg


Фантазии на большее сходу не хватило :) Но - у всех были в жизни, думаю, огромные (в плане колонок) таблички с пропертями сущностей, которые при проектировании не догадались вынести из одной таблички в 3 со связью "многие-ко-многим".
В этом случае ожидается результат, например, в виде строки - 'NAME George Georgy; DINPUT 01/02/2014 03/02/2014'
Наверное в результирующей строке для разделения значений имело бы смысл ввести какой-то спец.разделитель
6 фев 14, 13:36    [15528276]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
. Стоит задача - сравнить две заданные строки.

Так в чем проблема то ? Написать оператор сравнения между двумя полями ?
CASE WHEN t1.code = t2.code THEN 'CODE =' ELSE 'CODE <>' END as result_for_CODE
6 фев 14, 13:38    [15528311]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Glory
Vadim Romanenko
. Стоит задача - сравнить две заданные строки.

Так в чем проблема то ? Написать оператор сравнения между двумя полями ?
CASE WHEN t1.code = t2.code THEN 'CODE =' ELSE 'CODE <>' END as result_for_CODE
А считать ли, что NULL=NULL или нет?
6 фев 14, 13:42    [15528345]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
А считать ли, что NULL=NULL или нет?

Для меня - не считать, а для ТС - кто знает
6 фев 14, 13:44    [15528366]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Glory
iap
А считать ли, что NULL=NULL или нет?

Для меня - не считать, а для ТС - кто знает
Часто бывает, что большинство полей IS NULL.
В таком случае всегда записи будут отличаться друг от друга.
6 фев 14, 14:04    [15528547]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
Glory
пропущено...

Для меня - не считать, а для ТС - кто знает
Часто бывает, что большинство полей IS NULL.
В таком случае всегда записи будут отличаться друг от друга.

В каждой конкретной задаче есть свои конкретные требования/критерии сравнения
6 фев 14, 14:05    [15528563]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory
Vadim Romanenko
. Стоит задача - сравнить две заданные строки.

Так в чем проблема то ? Написать оператор сравнения между двумя полями ?
CASE WHEN t1.code = t2.code THEN 'CODE =' ELSE 'CODE <>' END as result_for_CODE


Не кошерно так :) Повторюсь, когда проблема кроется в таблице с 5-ю колонками - это одно, а когда в таблице 20 и не побоюсь этого слова 30 колонок - то писать такой кейс утомительно. А теперь представьте, что мне нужно считать различия в 10 таких таблицах :)
Не, я начал примерно так, как Вы написали. Но возникла мысль - а что если есть более "правильное" решение?
Вот, помнится, когда-то читал, что можно колонки таблицы развернуть в строки, и тогда при помощи MINUS наверное было бы как-то проще... А может и нет.

iap
А считать ли, что NULL=NULL или нет?

В моем случае NULL таки равно NULL
6 фев 14, 14:23    [15528703]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
Не кошерно так :) Повторюсь, когда проблема кроется в таблице с 5-ю колонками - это одно, а когда в таблице 20 и не побоюсь этого слова 30 колонок - то писать такой кейс утомительно. А теперь представьте, что мне нужно считать различия в 10 таких таблицах :)

Не понял. Вы хотите, чтобы сервер одной командой
- сравнил поля
- и преобразовал их все к одному типу ?

Vadim Romanenko
Вот, помнится, когда-то читал, что можно колонки таблицы развернуть в строки, и тогда при помощи MINUS наверное было бы как-то проще... А может и нет.

Вы уже определитесь что вы сраниваете - отдельные поля или множества
Аналогом MINUS в TSQL является EXCEPT. Только визуализация результата не та, которая вам нужна
6 фев 14, 14:29    [15528741]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Vadim Romanenko,

тогда подружитесь с sys.columns И с динамическими запросами - и генерите CASE и не парьтесь

что-то вроде

select 'case when t1.'+name+' != t2.'+name + ' then '''+name +' != '+name +''' else '''+ name +' == '+name +''' end'
from sys.columns

IsNULL - сами добавьте
6 фев 14, 14:35    [15528802]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Alexander Us
Member

Откуда:
Сообщений: 1161
Vadim Romanenko,

Вы как то нечётко определяете задачу.
Привели бы (упрощённые) примеры...

Что и как Вам надо савнивать?

Пример1: простое сравнение типа Col1=Col1, Col1 like ...
Таблица1: George
Таблица2: George
Таблица3: Mike

Пример2: нечёткое сравнение (тут George=Georgy) (функкция Левенштайна и т.д.)
Таблица1: George
Таблица2: Georgy
Таблица3: Mike

Пример3: ну очень нечётное сравнение
Таблица1: Бендер и Со
Таблица2: Бендер и Воробьянинов
Таблица3: ВоробьянинАв и партнёры
Таблица4: ООО Финансоыве услуги Рога и Копыта. Владельцы Бендер и Воробьянинов.
6 фев 14, 16:12    [15529655]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory
Vadim Romanenko
Не кошерно так :) Повторюсь, когда проблема кроется в таблице с 5-ю колонками - это одно, а когда в таблице 20 и не побоюсь этого слова 30 колонок - то писать такой кейс утомительно. А теперь представьте, что мне нужно считать различия в 10 таких таблицах :)

Не понял. Вы хотите, чтобы сервер одной командой
- сравнил поля
- и преобразовал их все к одному типу ?

Смотрите. Предположим у меня есть таблица с 30-ю колонками. В ней, например, журнал изменений некоей сущности. Ну пусть эта сущность будет "Абонент" для ясности. Я хочу понять, какие свойства "Абонента" изменились между двумя срезами. Именно двумя. Т.е. есть две строки в таблице, два ИД, по ним и хочется провести сравнение. В табличке выше - изменились свойства Имя и Дата. Чтоб было понятно, почему написание CASE-ов нежелательно - предлагаю представить, что табличек типа "Абонент" - десяток, в каждой табличке - от 20 до 30 колонок. Застрелиться можно столько CASE-ов написать ;)

Vadim Romanenko
Вот, помнится, когда-то читал, что можно колонки таблицы развернуть в строки, и тогда при помощи MINUS наверное было бы как-то проще... А может и нет.

Вы уже определитесь что вы сраниваете - отдельные поля или множества
Аналогом MINUS в TSQL является EXCEPT. Только визуализация результата не та, которая вам нужна[/quot]
Я сравниваю все поля таблицы в двух строках за исключением ключевых. На крайний случай можно и ключевые сравнить - просто эти поля искуственно удалить из результата.

Мне видится, что ТЕОРЕТИЧЕСКИ если бы можно было развернуть колонки таблицы в строки (по данным двух выбранных исходных строк), то операция MINUS дала бы в результате только строки с именами и значениями колонок, которые изменены... Как-то так.

Но, наверное, это все либо невозможно, либо слишком сложно :)

По всей видимости, для "кошерного" решения проблемы нужно копать таки в сторону Dynamic SQL.
6 фев 14, 16:36    [15529868]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
Смотрите. Предположим у меня есть таблица с 30-ю колонками. В ней, например, журнал изменений некоей сущности. Ну пусть эта сущность будет "Абонент" для ясности. Я хочу понять, какие свойства "Абонента" изменились между двумя срезами. Именно двумя. Т.е. есть две строки в таблице, два ИД, по ним и хочется провести сравнение. В табличке выше - изменились свойства Имя и Дата. Чтоб было понятно, почему написание CASE-ов нежелательно - предлагаю представить, что табличек типа "Абонент" - десяток, в каждой табличке - от 20 до 30 колонок. Застрелиться можно столько CASE-ов написать ;)

Вы можете
- не писать CASE и не решать задачу
- писать CASE и решать задачу
6 фев 14, 16:39    [15529895]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Alexander Us
Vadim Romanenko,

Вы как то нечётко определяете задачу.
Привели бы (упрощённые) примеры...

Что и как Вам надо савнивать?

Пример1: простое сравнение типа Col1=Col1, Col1 like ...
Таблица1: George
Таблица2: George
Таблица3: Mike

1. Интересует четкое, простое сравнение на равенство
2. Таблица у меня ОДНА :) Сравниваются две СТРОКИ одной таблицы
6 фев 14, 16:41    [15529908]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory
Вы можете
- не писать CASE и не решать задачу
- писать CASE и решать задачу

Я бы добавил еще один вариант:
- не писать CASE, заморочиться с динамическим SQL.

Правда что-то мне подсказывает, что гораздо реальней эту задачу решать не на сервере, а на клиенте - через какую-нибудь жаву или С# с библиотеками, которые по имени таблицы расковыряют ее колонки, сгенерят кейсы и выдадут результат.
6 фев 14, 16:45    [15529932]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
Я бы добавил еще один вариант:
- не писать CASE, заморочиться с динамическим SQL.

А в динамическом запросе CASE не будет что ли ?
6 фев 14, 16:46    [15529939]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory
Vadim Romanenko
Я бы добавил еще один вариант:
- не писать CASE, заморочиться с динамическим SQL.

А в динамическом запросе CASE не будет что ли ?


Я предполагаю, что в динамическом запросе я напишу кейс один раз, а дальше в цикле размножу его по количеству колонок ;) и не надо будет копипастить 20 раз, заменяя в каждой строчке имена колонок в нескольких местах, что неизбежно приведет к отрицательному эффекту копипаста. Имеется ввиду, что где-то да всунется левая колонка в ненужном месте...
6 фев 14, 17:04    [15530028]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Vadim Romanenko
Я предполагаю, что в динамическом запросе я напишу кейс один раз, а дальше в цикле размножу его по количеству колонок ;) и не надо будет копипастить 20 раз, заменяя в каждой строчке имена колонок в нескольких местах, что неизбежно приведет к отрицательному эффекту копипаста.

А как вы будете формировать из полей разных типов строку вида "'NAME George Georgy; DINPUT 01/02/2014 03/02/2014'" вы уже тоже подумали ?
6 фев 14, 17:06    [15530041]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Glory,

Да нет конечно :)
В случае, если бы я мог транспонировать две строки таблицы, то там все было бы достаточно элементарно.
В случае динамического SQL - признаюсь - в MS SQL Server я с ним не работал, потому вообще не представляю, как.

На данный момент, в результате дискуссии выше, вижу только два реальных способа решения задачи:
- втупую - написать нужное количество CASE-ов
- сложно, но можно с заделом на будущее - анализ выполнять на стороне клиента; способ заключается в создании утилиты, которая на вход получает имя таблицы, имя ключевого поля и пару ИД для сравнения, дальше - вся логика висит внутри, на выходе - строка нужного формата.

Признаюсь, что на данный момент решил проблему втупую :(
6 фев 14, 17:39    [15530237]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
как вариант,
declare @convert table (
   PK       int
   ,NAME    varchar(max)
   ,CODE    varchar(max)
   ,DINPUT  varchar(max)
   ,VDIR    varchar(max)
   ,VFILE   varchar(max)
   );

/*with myTable as (select * from (values
   (1,'George','GG',convert(date,'20140201'),'D:\GG\SelfPath','gg.cfg')
   ,(2,'Georgy','GG','20140203','D:\GG\SelfPath','gg.cfg')
   )values_myTable(PK,NAME,CODE,DINPUT,VDIR,VFILE)
)*/
insert @convert (PK,NAME,CODE,DINPUT,VDIR,VFILE) 
   select PK,NAME,CODE,DINPUT,VDIR,VFILE 
   from myTable

select u.nm, min(u.val) mn,max(u.val)mx
from @convert a
unpivot(val for nm in (NAME, CODE, DINPUT, VDIR, VFILE))u
group by u.nm
having min(u.val)!=max(u.val)
order by u.nm
nm mn mx
DINPUT 2014-02-01 2014-02-03
NAME George Georgy
Никаких CASE, скопировать в буфер названия всех столбцов и воткнуть в 3 места тоже не сложно
6 фев 14, 17:56    [15530341]     Ответить | Цитировать Сообщить модератору
 Re: Разница между двумя записями в таблице  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Cygapb-007,

Браво! Я правда нифига не понял - буду разбираться... Но - видать, работает :) Спасибо!
6 фев 14, 18:16    [15530459]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить