Kern
Гость
|
|
« : 08-12-2003 13:37 » |
|
Допустим есть таблица CREATE TABLE tab )id int, date_time timestamp without time zone, string varchar)30:,PRIMARY KEY)id::; и заполнена она примерно таким образом: 1, '2003.08.12 12:00', 'timber' 2, '2003.08.12 12:00', 'timber' 4, '2003.08.12 13:00', 'kern' 6, '2003.08.12 13:01', 'hack' 7, '2003.08.12 13:05', 'timber' 8, '2003.08.12 13:07', 'timber' 10, '2003.08.12 13:07', 'timber' 12, '2003.08.12 13:08', 'hack'[/list:u] Так вот, надо удалить "повторяющиеся записи", оставив первое вхождение в данном случае это строчки с id=(2,8,10) SQL - запросом. Допустимо использовать несколько одинаковых SQL вподряд. Упрощение - строка не может повторяться более 5 раз.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 08-12-2003 17:44 » |
|
Попробуй так: SELECT t1.id FROM table AS t1 LEFT JOIN table AS t2 ON t2.id=)t1.id+1: WHERE t1.date_time=t2.date_time AND t1.string=t2.string; Удалять на основании полученных данных (id повторных строк). Если СУБД поддерживает вложенные запросы, то: DELETE FROM table WHERE id IN )SELECT ...:; Недостаток: СУБД должна поддерживать работу с одной и той же таблицей с разными псевдонимами. Данный пример может быть некоректным, но ход мыслей верный. Этот код не проверял, но такой же код у меня работал на MySQL - искал пропуски в id.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Alf
Гость
|
|
« Ответ #2 : 08-12-2003 21:25 » |
|
Попробуй так: SELECT t1.id FROM table AS t1 LEFT JOIN table AS t2 ON t2.id=)t1.id+1: WHERE t1.date_time=t2.date_time AND t1.string=t2.string; ... Поленился проверить на реальном сервере, но показалось, что в данном решении имеется пара неувязочек. Первая - совсем мелкая. По условию нужно удалять все дубликаты, кроме первого вхождения. А тут как раз первое вхождение и становится жертвой удаления. Но это ерунда, заменить id+1 на id-1 - и вроде должно заработать. А вот вторая посерьезнее будет. В приведенном выше запросе мы закладываемся на то, что нумерация записей - последовательная. Но из примера видно, что это не так. Например, записи с id=(8,10) под условие явно не попадают и обнаружены не будет. По моему опыту, красивое непроцедурное решение подобных задач в общем случае удается найти нечасто, только если на данные наложены строгие ограничения, как в данном случае - последовательная нумерация id. На мой взгляд, единственный выход - в процедурном решении: заводить курсор, сканировать записи по одной и выбрасывать дубликаты. Некрасиво, конечно, но зато работает.
|
|
|
Записан
|
|
|
|
Kern
Гость
|
|
« Ответ #3 : 09-12-2003 05:59 » |
|
тогда как вариант - можно создать временную табличку и скопировать туда оригинальную CREATE TEMP TABLE temp_table )id AUTOINCREMENT, tab_id int, string varchar)30:, PRIMARY KEY )id::; INSERT INTO temp_table VALUES)tab_id,string: SELECT id,string FROM tab ORDER BY date_time; здесь AUTOINCREMENT - какое-либо средство БД обеспечить автоматическое инкрементирование. И уже к этой табличке применять SELECT с LEFT JOIN и т.п... а на основе его удалать из оригинальной.... а потом и временную табличку грохнуть... мда... при таких изврашениях и при очень большой таблице - IMHO это слишком накладно....
|
|
|
Записан
|
|
|
|
little
|
|
« Ответ #4 : 09-12-2003 07:33 » |
|
А насколько критичны имеющиеся ID ? Если они не нужны, сделать Select Distinct или Distinctrow (не помню чем они отличаются), а в результате проставить новые ID
|
|
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #5 : 09-12-2003 07:41 » |
|
Для проверки записей для удаления SELECT tmpid FROM )SELECT MIN)id: as tmpid, date_time, string FROM tab GROUP BY date_time, string: AS tmp: если то что надо, тогда DELETE FROM tab WHERE id NOT IN )SELECT tmpid FROM )SELECT MIN)id: as tmpid, date_time, string FROM tab GROUP BY date_time, string: AS tmp:: проверял, работало ЗЫЖ на всякий случай сделай копию
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
Kern
Гость
|
|
« Ответ #6 : 09-12-2003 08:44 » |
|
HandKot, Проверил код, не удаляется запись с ID=8. Если запрос на удаление повторить - то все равно более ничего не удаляется.
|
|
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #7 : 09-12-2003 09:54 » |
|
Kern, А почему она должна удалить запись с id=8 Запрос удалил запись с id=10 -> осталась запись №8 повторяющихся записей больше нет
объясни получше, не могу понять
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
RXL
|
|
« Ответ #8 : 09-12-2003 11:17 » |
|
Kern, А почему она должна удалить запись с id=8 Запрос удалил запись с id=10 -> осталась запись №8 повторяющихся записей больше нет
объясни получше, не могу понять Потому что, она дублирует строку с id=7. little, так нельзя. Нужно удалить строки не повторяющиеся во всей базе, а лишь следующие друг за другом в порядке id.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #9 : 09-12-2003 12:39 » |
|
7, '2003.08.12 13:05', 'timber' 8, '2003.08.12 13:07', 'timber'
RXL, время разное - > записи не дублируются или нужен отсев по часам?
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
RXL
|
|
« Ответ #10 : 09-12-2003 12:48 » |
|
HandKot, извиняй - округлил малость Кстати, действительно - пробел в задании: что есть "повторяющиеся записи"? Если у них может быть разное время, то какая разница допустима (для смежных и крайних в последовательной группе)?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kern
Гость
|
|
« Ответ #11 : 10-12-2003 05:52 » |
|
HandKot, RXL, "повторяющиеся записи" это записи, имеющие одинаковое поле string и идущие друг за другом после SELECT * FROM tab ORDER BY date_time; То есть табличка tab - это нечто вроде журнала событий и нужно убрать все подряд идущие одинаковые события, оставив только первое из них.
|
|
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #12 : 10-12-2003 06:45 » |
|
Kern, тогда в этом случае SQL для выборки SELECT T1.id FROM tab AS T1 WHERE T1.string LIKE )SELECT TOP 1 T2.string FROM tab AS T2 WHERE T1.id > T2.id ORDER BY T2.date_time DESC: и SQL для удаления DELETE FROM tab WHERE id IN )SELECT T1.id FROM tab AS T1 WHERE T1.string LIKE )SELECT TOP 1 T2.string FROM tab AS T2 WHERE T1.id > T2.id ORDER BY T2.date_time DESC:: ЗЫ вместо оператора LIKE можно поставить = и не забудь сделать копию таблицы, на всякий случай [/b]
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
Kern
Гость
|
|
« Ответ #13 : 10-12-2003 15:17 » |
|
HandKot, SELECT дает не те записи - точнее дает только одного timber и выдает ID-шники всех timber'ов идущех после первого (2,7,8,10) но 7-ой то не должен удаляться - он же не вподряд после timber идет - он уже после hack идет. если в табличку добавить еще парочку записей, например 14, '2003.08.12 13:09', 'hack' 9, '2003.08.12 14:04', 'hack'[/list:u] (Если присмотреться - то можно заметить что ID-шники идут не по порядку ) то они все равно не выделяются данным SELECTом. (если сделать ID по порядку - то же самое) Ключевое слово TOP - моя БД не поняла (Postgress 7.2 может там что-то по другому написать нада) так что SELECT пришлось заменить на
SELECT T1.id,T1.date_time,T1.string FROM tab AS T1 WHERE T1.string LIKE )SELECT string FROM tab WHERE id=)SELECT min)T2.id: FROM tab AS T2 WHERE T1.id > T2.id:: ORDER BY date_time;
|
|
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #14 : 11-12-2003 08:17 » |
|
Kern, твой запрос у меня вообще отработал не правильно
входные данные: 1 2003-08-12 12:00:00.000 timber 2 2003-08-12 12:00:00.000 timber 4 2003-08-12 13:00:00.000 kern 6 2003-08-12 13:01:00.000 hack 7 2003-08-12 13:05:00.000 timber 8 2003-08-12 13:07:00.000 timber 10 2003-08-12 13:07:00.000 timber 12 2003-08-12 13:08:00.000 hack 14 2003-08-12 13:09:00.000 hack 9 2003-08-12 14:04:00.000 hack
выходые данные: 2 2003-08-12 12:00:00.000 timber 7 2003-08-12 13:05:00.000 timber 8 2003-08-12 13:07:00.000 timber 10 2003-08-12 13:07:00.000 timber
странно может разница в реализации SQL?
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #15 : 11-12-2003 08:24 » |
|
Kern, вот еще один запросик от меня, проверь SELECT id, string, dtmdate FROM )SELECT min)id: as id, date_time, string from tab group by date_time, string: as t WHERE string not like )SELECT TOP 1 tmp.string FROM tab AS tmp WHERE t.date_time > tmp.date_time ORDER BY tmp.date_time desc: or not exists )SELECT TOP 1 tmp.string FROM tab AS tmp WHERE t.date_time > tmp.date_time ORDER BY tmp.date_time desc:
order by t.date_time
вот результаты: входные данные: 1 2003-08-12 12:00:00.000 timber 2 2003-08-12 12:00:00.000 timber 4 2003-08-12 13:00:00.000 kern 6 2003-08-12 13:01:00.000 hack 7 2003-08-12 13:05:00.000 timber 8 2003-08-12 13:07:00.000 timber 10 2003-08-12 13:07:00.000 timber 12 2003-08-12 13:08:00.000 hack 14 2003-08-12 13:09:00.000 hack 9 2003-08-12 14:04:00.000 hack выходные данные: 1 timber 2003-08-12 12:00:00.000 4 kern 2003-08-12 13:00:00.000 6 hack 2003-08-12 13:01:00.000 7 timber 2003-08-12 13:05:00.000 12 hack 2003-08-12 13:08:00.000 Запрос немного корявый (самому не нравиться ), но вроде работает и по поводу команды "TOP" - стандартная SQL команда, для выборки только первой записи из набора записей (может в твоем случае есть похожие типа FIRST, ..., и т.д.) ЗЫЖ Проверь и сообщи.
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
Kern
Гость
|
|
« Ответ #16 : 11-12-2003 13:32 » |
|
HandKot, Ёу! запрос что нада в моем случае вместо TOP нада использовать LIMIT: SELECT id, string, date_time FROM )SELECT min)id: as id, date_time, string from tab group by date_time, string: as t WHERE string not like )SELECT tmp.string FROM tab AS tmp WHERE t.date_time > tmp.date_time ORDER BY tmp.date_time desc LIMIT 1: or not exists )SELECT tmp.string FROM tab AS tmp WHERE t.date_time > tmp.date_time ORDER BY tmp.date_time desc LIMIT 1:
order by t.date_time Входные-выходные данные точно такие же, при усложнении данных (типа добавление таблички tab самой к себе со смещенным временем и id) тоже пахает как нада! Сколько нада с SQL-ом работать чтобы дорасти до таких "приятностей"?
|
|
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #17 : 11-12-2003 13:46 » |
|
1,5 часа и напарник
|
|
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
Raf^Dimas
Гость
|
|
« Ответ #18 : 04-03-2004 18:35 » |
|
|
|
|
Записан
|
|
|
|
Raf^Dimas
Гость
|
|
« Ответ #19 : 04-03-2004 18:38 » |
|
Objasnite plzzzzz kak namana mo#no vvesti vse kodi 4to oni rabotali i dlja 4ego oni voob6e zna4at
|
|
|
Записан
|
|
|
|
Raf^Dimas
Гость
|
|
« Ответ #20 : 04-03-2004 18:41 » |
|
Ili mo#et kto sajt znaet kakoj nibudj 4tob tam Hack Cheat ili 4to libo drugoe bilo na MU
|
|
|
Записан
|
|
|
|
Anonymous
Гость
|
|
« Ответ #21 : 04-03-2004 18:45 » |
|
Kern, Objasni popodrobnee kak i 6to delatj
|
|
|
Записан
|
|
|
|
Kern
Гость
|
|
« Ответ #22 : 05-03-2004 04:42 » |
|
Raf^Dimas, Я не врубился чего ты не понял Что такое MU? про какие коды ты говоришь? про id? короче, чего тебе надо? (если можешь пиши лучше на нормальном русском)
|
|
|
Записан
|
|
|
|
|