![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Определение дубля
Dvm_home © (2005-06-16 05:36:00)Здравствуйте Мастера!
Имеется таблица заявок на MS SQL:
CREATE TABLE [DeliveryDeliv] (
[DeliveryID] int NOT NULL,
[DateDeparture] datetime NOT NULL,
[TimeDeparture] smallint NOT NULL,
[NameGoods] char(60) COLLATE Cyrillic_General_CI_AS,
[GoodsSerialNumber] char(30) COLLATE Cyrillic_General_CI_AS,
[ShopName] char(100) COLLATE Cyrillic_General_CI_AS,
[Customer] char(50) COLLATE Cyrillic_General_CI_AS,
[CustomerRegion] char(50) COLLATE Cyrillic_General_CI_AS,
[CustomerStreet] char(50) COLLATE Cyrillic_General_CI_AS NOT NULL,
[CustomerHouse] char(10) COLLATE Cyrillic_General_CI_AS NOT NULL,
[CustomerFlat] char(10) COLLATE Cyrillic_General_CI_AS,
[CustomerPhone] char(20) COLLATE Cyrillic_General_CI_AS,
[AdressComent] char(300) COLLATE Cyrillic_General_CI_AS,
[Comment] char(400) COLLATE Cyrillic_General_CI_AS,
[StatusID] tinyint NOT NULL,
[TimeComent] char(20) COLLATE Cyrillic_General_CI_AS,
[TeamID] int,
[MotiveID] int,
[NumberGoodsInDelivery] tinyint,
[Created] datetime,
[CreateUserID] int,
[LastUpdated] datetime,
[UpdatedUserID] int,
[DeliveryFromStore] tinyint,
[DateMail] datetime,
[MailAdressID] int,
CONSTRAINT [DeliveryDeliv_pk] PRIMARY KEY ([DeliveryID])
)
ON [PRIMARY]
GO
Необходимо узнать на какие адреса (CustomerStreet, CustomerHouse, CustomerFlat) заявки оформлялить больше одного раза.
запрос типа:
Select *, COUNT(DeliveryID) from DeliveryDeliv GROUP BY CustomerStreet, CustomerHouse, CustomerFlat
не проходит, ругается на все поля не входящие в GROUP. Пробовал использовать временную таблицу и курсор - таже история.
Danilka (2005-06-22 10:02:00) [1]
> Я же написал, что это черновик, индексы и все прочее добавится
> по ходу дела.
Надо с самого начала проектировать правильно, стараясь учеть как можно больше нюансов. Если-бы ты так сделал изначально, и вместо того, чтобы понимать "идиалогию реляционных отношений" применял-бы это на практике, скорее всего, данная задача не возникла-бы вообще.
Dvm_home (2005-06-22 02:55:00) [2]Вопрос по поводу использования временных таблиц и курсоров остается актуальным
Dvm_home (2005-06-22 02:53:00) [3]Привет Всем
Почитал я последние посты, немного посмеялся. "Нереагировал" я потому что рабочий день кончилси :), и идиалогию реляционных отношений понимаю.
Я же написал, что это черновик, индексы и все прочее добавится по ходу дела.
Спасибо ЮЮ за конструктив, МОА - на кашелек операторов воздействовать никак не получится - я работаю в этой компании.
--> ЮЮ
Почему
> CustomerStreet, CustomerHouse, CustomerFlat - не
> лучший набор полей как для группировки, так и для
> соединения
Anatoly Podgoretsky (2005-06-16 13:23:00) [4]ЮЮ © (16.06.05 11:35) [27]
Копит деньги на бутылку.
Но похоже он плохо понимает идеологию реляционных отношений.
ЮЮ (2005-06-16 11:35:00) [5]Без Dvm_home всё равно спор не разрешить, а он уже 40 минут не реагирут :)
Danilka (2005-06-16 11:32:00) [6][24] ЮЮ © (16.06.05 11:26)
впрочем, можем посприть и сейчас, ставлю бутылку пива, если окажусь в твоих краях, или ты окажешься в моих. :))
Danilka (2005-06-16 11:30:00) [7][24] ЮЮ © (16.06.05 11:26)
медленнее будет, факт, раз у него нет индексов по полям: CustomerStreet, CustomerHouse, CustomerFlat, а именно по этим полям ты и соединяешься.
Хотя, может и не медленнее моего, если учесть, что записей с повторами мало. Но если сделать идекс составной, то могу поспорить на полом серьезе, что мой запрос будет быстрее твоего. :))
Кроме того, интересно почему он не группирует еще и по регионам? Это тоже часть адреса.
ЮЮ (2005-06-16 11:26:00) [8]спорим, будет больше моих 2.78с.? :))
Спорим нет! Ибо он не должен быть медленнее [4], который 0.78
Danilka (2005-06-16 11:21:00) [9][22] ЮЮ © (16.06.05 11:08)
спорим, будет больше моих 2.78с.? :))
если индексов нет, то толку от таких соединений?
вообще, кадр забавный, у него, значит, юзеры ленивые, улицу могут несколько раз разными буковками забить, даже если будут выбирать адрес клиента из таблицы адресов уже отфильтрованой по выбраному клиенту.
поэтому о нормализации говорить низзя. наверное, об индексах низзя говорить по той-же причине. :)
ЮЮ (2005-06-16 11:08:00) [10]в MS SQL есть ещё подзапросы:
SELECT tbl.*
FROM
(
SELECT
CustomerStreet, CustomerHouse, CustomerFlat,
COUNT(DeliveryID) OneAddressCount
FROM
DeliveryDeliv
GROUP BY
CustomerStreet, CustomerHouse, CustomerFlat
HAVING
COUNT(DeliveryID) > 1
) gr
JOIN DeliveryDeliv tbl ON
(gr.CustomerStreet = tbl.CustomerStreet) AND
(gr.CustomerHouse= tbl.CustomerHouse) AND
(gr.CustomerFlat= tbl.CustomerFlat)
Т.е. в запросе находишь те параметры, которые, окажись они в записи таблицы, тебя интересуют. И затем соединяешь запрос с таблицей по полученным значениям.
Естественно, в твоем случае, CustomerStreet, CustomerHouse, CustomerFlat - не лучший набор полей как для группировки, так и для соединения
MOA (2005-06-16 11:04:00) [11]>Мне пришлось отказаться от справочника улиц потому что операторы пишут названия как хотят
В этом случае Ваш запрос будет не только медленным, но и выдавать числа прошлогоднего календаря, а не "на какие адреса заявки оформлялить больше одного раза."
Нормализация нужна, в частности, и для этого. А на лом операторов хорошо действует кошелёк ;).
Удачи!
Dvm_home (2005-06-16 10:53:00) [12]Anatoly Podgoretsky © (16.06.05 10:04) [13]
Получается что в одном запросе никак не укажешь другие поля кроме тех что в GROUP. Вот я и прошу помочь с временными таблицами и курсорами
Dvm_home (2005-06-16 10:48:00) [13]Нет таблица не единственная :). Это сделано не из хорошей жизни. Мне пришлось отказаться от справочника улиц потому что операторы пишут названия как хотят, первичка сыпется валом и им видетели влом смотреть что почти всегда программа при проверке адреса им справочником тычет. Потом количество таких двойных заявок не велико от общего числа. Ну и последнее все это портируется из клариона, находится в стадии разбора и далеко от конечного варианта. :)
Anatoly Podgoretsky (2005-06-16 10:37:00) [14]Ну то что тут нет никакой нормализации это факт, но не единственный недостаток. Страшно подумать, но возможно это вообще единственная таблица.
Danilka (2005-06-16 10:30:00) [15]и вообще, если на один адрес может быть несколько доставок, то намного правильнее было-бы вынести вот-это:
[CustomerRegion] char(50) COLLATE Cyrillic_General_CI_AS,
[CustomerStreet] char(50) COLLATE Cyrillic_General_CI_AS NOT NULL,
[CustomerHouse] char(10) COLLATE Cyrillic_General_CI_AS NOT NULL,
[CustomerFlat] char(10) COLLATE Cyrillic_General_CI_AS,
[AdressComent] char(300) COLLATE Cyrillic_General_CI_AS,
в отдельную таблицу. Customer-а с телефоном и прочими атрибутами тоже в свою таблицу.
также, нехило было-бы регионы и улицы тоже сделать отдельными таблицами, а в таблицу адреса писать их идентификаторы а не названия.
ну и еще, дофига чего можно напридумывать. а так, вся эта беда через год будет жрать не 0.78с, а счет может пойти на минуты. и это не единственная и не самая страшная проблема из тех, которые обязательно возникнут.
Danilka (2005-06-16 10:09:00) [16][13] Anatoly Podgoretsky © (16.06.05 10:04)
Все странно, начиная с запроса в [4] :)
ANB (2005-06-16 10:08:00) [17]1. ТЗ не соответствует сабжу и не понятно. По каким критериям :
Необходимо узнать на какие адреса (CustomerStreet, CustomerHouse, CustomerFlat) заявки оформлялить больше одного раза.
???
Danilka (2005-06-16 10:08:00) [18][11] Dvm_home (16.06.05 09:37)
> Работает, вот только время выборки 2.78, а если так как
> я сделал в [4] то 0.78
Значит нет индексов по всем полям участвующим в условии WHERE.
Попробуй сделать один составной индекс по полям CustomerStreet, CustomerHouse и CustomerFlat, будет еще быстрее, чем твои 0.78.
Anatoly Podgoretsky (2005-06-16 10:04:00) [19]Dvm_home (16.06.05 09:37) [11]
Странно как то, зачем тебе данные с DeliveryID из одной записи, DateDeparture из другой записи. Какой особый смысл в этом вообще и по отдельным полям в частности?
Dvm_home (2005-06-16 09:45:00) [20]Может еще подскажете как использовать временные таблицы и курсоры. Например в применении к этой задаче
сделать что то типа:
Select CustomerStreet, CustomerHouse, CustomerFlat
FROM DeliveryDeliv INTO temp
GROUP BY CustomerStreet, CustomerHouse, CustomerFlat
HAVING COUNT(DeliveryID) > 1
и потом
SELECT a.*
FROM DeliveryDeliv a, temp t
WHERE a.CustomerStreet = t.CustomerStreet
AND a.CustomerHouse = t.CustomerHouse
AND a.CustomerFlat = t.CustomerFlat