|
v7: Запрос на Sqlite | ☑ | ||
---|---|---|---|---|
0
Sam1C
16.02.18
✎
12:23
|
доброго дня! может кто подскажет идейку как выбрать для справочника контрагента последний документ определенного вида. Пока только в голову лезут выборка всех контрагентов и потом подзапросами по каждому выбирать Последний док. Но 10000 контрагентов 10000 подзапросов, что-то ни оптимально
|
|||
1
Ёпрст
16.02.18
✎
12:27
|
(0)
обычный коррелированный подзапрос в селекте |
|||
2
Ёпрст
16.02.18
✎
12:29
|
ну или селект клиентос из справочника + лефт джоин (селект клиентос фром документ + гроуп бай клиентосу и максимум дата и всё
|
|||
3
Sam1C
16.02.18
✎
13:15
|
(2)
SELECT Контрагенты.ID [Ссылка :Справочник.Контрагенты] , Контрагенты.Менеджер [Менеджер :Справочник.Менеджеры] , срм_Событие.IDDOC [срм_СобытиеСсылка :Документ.срм_Событие] , Max(Журнал.DATE) МаксимумДокумент_дата FROM [Справочник.Контрагенты] AS Контрагенты LEFT OUTER JOIN [Документ.срм_Событие] AS срм_Событие ON Контрагенты.ID = срм_Событие.шКонтрагент LEFT OUTER JOIN [_1S.JOURN] AS Журнал ON срм_Событие.IDDOC = Журнал.IDDOC GROUP BY Контрагенты.ID , Контрагенты.Менеджер , срм_Событие.IDDOC |
|||
4
Sam1C
16.02.18
✎
13:18
|
(3) Что я делаю ни так? выдает все документы по каждому контрагенту, а не последний
|
|||
5
alxxsssar
16.02.18
✎
13:22
|
(4) Группировки у тебя не излишние? По Менеджеру и Событию (Тем более я так понимаю это документ) зачем группировать?
|
|||
6
Sam1C
16.02.18
✎
13:27
|
(5) согласен, щас оставлю только по Контрагенту по пробую
|
|||
7
alxxsssar
16.02.18
✎
13:29
|
(6) из итоговых полей не забудь удалить, а то ошибка будет
|
|||
8
Sam1C
16.02.18
✎
13:33
|
(7) какие итоговых?, я удаляю только из GROUP BY. Мне же в ТЗ нужна ссылка на документ, а не только его дата:
SELECT Контрагенты.ID [Ссылка :Справочник.Контрагенты] , Контрагенты.Менеджер [Менеджер :Справочник.Менеджеры] , срм_Событие.IDDOC [срм_СобытиеСсылка :Документ.срм_Событие] , Max(Журнал.DATE) МаксимумДокумент_дата FROM [Справочник.Контрагенты] AS Контрагенты LEFT OUTER JOIN [Документ.срм_Событие] AS срм_Событие ON Контрагенты.ID = срм_Событие.шКонтрагент LEFT OUTER JOIN [_1S.JOURN] AS Журнал ON срм_Событие.IDDOC = Журнал.IDDOC GROUP BY Контрагенты.ID |
|||
9
alxxsssar
16.02.18
✎
13:36
|
менеджера и событие. Иначе запрос ошибку выдаст, что они не участвуют в group by
|
|||
10
Sam1C
16.02.18
✎
13:39
|
(9) не, тут пракатывает. в групп не обязательно все поля указывать которые есть в выборке. Короче запрос в (8) отработал на ура, данные верные, но 10 минут, это конечно не серьезно
|
|||
11
alxxsssar
16.02.18
✎
13:53
|
(10) поздравляю
|
|||
12
Sam1C
16.02.18
✎
14:25
|
(11) поздравлять не с чем. очень долго работает
|
|||
13
Darych
16.02.18
✎
14:33
|
(12) парси словарь, через ado к таблице дока скулевый запрос
|
|||
14
Ёпрст
16.02.18
✎
15:31
|
Тебе нужно найти max(idx_IDDOCDEF_DATE_TIME_IDDOC) и по этому полю отфильтровать
|
|||
15
alxxsssar
16.02.18
✎
15:41
|
(12) а сколько объектов в базе у тебя?
|
|||
16
alxxsssar
16.02.18
✎
15:43
|
(15) и может сделать сперва выборку документов, проиндексировать ее и джойнить контрагентов с этой таблицей по индексам?
|
|||
17
Ёпрст
16.02.18
✎
15:50
|
На вот, занимайся
select Спр.id [Клиентос:Справочник.Контрагенты] ,right(Таб.МаксПозиция,9) [Док:Документ.срм_Событие] from [Справочник.Контрагенты] Спр left join( select Док.Контрагент, max(idx_IDDOCDEF_DATE_TIME_IDDOC) МаксПозиция from Журнал Жур inner join [Документ.срм_Событие] Документ group by Док.Контрагент) Таб on Таб.Контрагент=Спр.id |
|||
18
Sam1C
16.02.18
✎
16:17
|
(15) да не много 10000 контрагентов 50000 документов этого вида
|
|||
19
alxxsssar
16.02.18
✎
16:25
|
(18) тогда даже для (8) это слишком долго. У меня 3 миллиона записей выбираются за 2,5 минуты
|
|||
20
alxxsssar
16.02.18
✎
16:26
|
+(19) тоже с пересчетами и джойнами конечно
|
|||
21
Djelf
16.02.18
✎
19:21
|
Отборы в журнале есть? Если есть по нужным критериям - можно использовать, должно ускорить.
> Но 10000 контрагентов 10000 подзапросов, что-то ни оптимально Можно развернуть логику в обратную сторону - первым в запросе выбирать самую тяжелую таблицу и применить к ней все возможные условия, это видимо Журнал и джойнить к нему, а не наоборот. 100500 подзапросов к тяжелой таблице и убивают скорость. |
|||
22
Злопчинский
16.02.18
✎
20:23
|
Интересно за сколько 17 отработает
|
|||
23
Djelf
17.02.18
✎
12:03
|
(22) Смотря на какой версии sqlite.
Оригинальная 1.0.2.6 на движке 3.7.10 будет выполнять запрос SELECT
за ~3с на 1.5м записей, умножаем на 10000 и плачем. А вот начиная с движка 3.7.16 этот запрос выполниться всего за 1мс т.к. движок начал понимать что если индекс упорядочен, то просматривать всю таблицу не имеет смысла. |
|||
24
Djelf
17.02.18
✎
13:56
|
(0) А это за сколько выполнится?
|
|||
25
mistеr
17.02.18
✎
14:44
|
Ограничить дату документов снизу неким разумным значением, например год. Выбрать все доки, сгруппировать по контрагенту, взять максимум.
|
|||
26
Ёпрст
17.02.18
✎
14:53
|
(24) этот запрос не вернёт всех клиентосов
|
|||
27
Ёпрст
17.02.18
✎
14:53
|
и это, нафига ты пишешь [_1S.JOURN] ...когда проще писать
Журнал ... |
|||
28
Ёпрст
17.02.18
✎
14:53
|
?
|
|||
29
Djelf
17.02.18
✎
15:39
|
(28) Так было написано у автора топика в (3).
Я не стал менять ;) (27) То правда! Тогда так:
|
|||
30
Ёпрст
17.02.18
✎
15:51
|
(29) последний group by лишний же
|
|||
31
Djelf
17.02.18
✎
15:59
|
(30) Да, перестраховался ;(
|
|||
32
SleepyHead
гуру
17.02.18
✎
18:08
|
Чем-то мне это все напоминает анекдот про Ржевского и господ офицеров, развлекавшихся с девушкой на бильярдном столе.
Господа, с вами все в порядке? Штатным языком 1с77 задача решается в три строки кода. |
|||
33
Злопчинский
17.02.18
✎
19:22
|
(32) жжошь!
|
|||
34
Djelf
17.02.18
✎
19:24
|
Ну вот пришел SleepyHead и все испортил ;(
А столько еще идей было... |
|||
35
Злопчинский
17.02.18
✎
19:32
|
СделатьВсе()
|
|||
36
Ёпрст
18.02.18
✎
19:38
|
(32) Ну напиши нам, эти строки,
так, на поржать |
|||
37
Aleksey
18.02.18
✎
19:51
|
(36) НУ в типовых Контрагент - это графа отбора, а значит
ВыбратьПоЗначению + ОбратныйПорядок Разве нет? |
|||
38
Ёпрст
18.02.18
✎
19:57
|
(37) у него не типповая и нет графы отбора + нужен определенный вид дока
|
|||
39
Ёпрст
18.02.18
✎
19:58
|
+ нужны все клиентосы, а не только те, по которым были документы.
|
|||
40
Ёпрст
18.02.18
✎
19:58
|
И да.. графа отбора, ничего не даст, в типовом случае :)))
|
|||
41
Ёпрст
18.02.18
✎
20:03
|
разве что перебор справочника клиентосов и для каждого выбратьпозначению с условием на вид дока в перебое..
но, это не наш метод, слишком долго |
|||
42
Aleksey
18.02.18
✎
20:21
|
Ну я так понимаю нужно просто в карточки клиента вывести список, чтобы как в 8-ке
|
|||
43
Sam1C
18.02.18
✎
20:24
|
(22) В (17) в подзапросе нет отбора по виду документа по этому он больше часа лопатит. И наверно нет функции right в SQlite вместо нее substr, substr (Таб.МаксПозиция,-9) походу делать так нужно.
|
|||
44
Sam1C
18.02.18
✎
20:27
|
Запрос в (8) работает 10 минут как говорилось выше, а вот (29) 18 секунд, спасибо Djelf.
|
|||
45
Sam1C
18.02.18
✎
20:54
|
(29) Только не могу понять за чем во вложенном запросе идет соединение со справочником Контрагенты:
LEFT JOIN [Справочник.Контрагенты] AS Контрагент ON Контрагент.ID=срм_Событие.шКонтрагент. Контрагента тянем то из документа для таблицы Выборка, зачем подключать еще справочник контрагентов Или это опечатка? |
|||
46
Ёпрст
19.02.18
✎
12:23
|
(43) есть там всё. Там иннер джоин
|
|||
47
Ёпрст
19.02.18
✎
12:24
|
Ну и (23) смотри - поставь другую версию 1sqlite
|
|||
48
Ёпрст
19.02.18
✎
12:24
|
(45) это лишнее
|
|||
49
SleepyHead
гуру
19.02.18
✎
12:27
|
(38) "Нет графы отбора"
Мыши плакали, кололись, но продолжали жрать кактус. Господа, мне с вами не по пути )) |
|||
50
Ёпрст
19.02.18
✎
12:40
|
(49) Покажи 3 строки с кодом, если есть графа отбора.
|
|||
51
Djelf
19.02.18
✎
13:11
|
(44) Если поставишь версию поновее будет ~8с
http://catalog.mista.ru/public/559826/ https://cloud.mail.ru/public/9znr/ZJ6ULE9aR Но предупреждаю - некоторые запросы могут начать тормозить, особенно с использованием IN. Так что сначала на копии прогони. (45) Не доводил до идеала. Все равно это видимо только часть запроса. |
|||
52
Sserj
19.02.18
✎
13:55
|
хех, а еще с скулайтом можно извратиться :)
Запрос.ВыполнитьЗапрос("CREATE TEMP TABLE ПоследниеДокументы (Клиент varchar(9) PRIMARY KEY, Док varchar(9))); Запрос.ВыполнитьЗапрос(" INSERT INTO ПоследниеДокумент (Клиент,Док) SELECT пДокументы.Клиент , пДокументы.Док FROM (SELECT срм_Событие.Контрагент as Клиент , Журнал.IDDOC as Док , Max(Журнал.idx_DATE_TIME_IDDOC) FROM Журнал Д JOIN Документ_срм_Событие AS срм_Событие ON срм_Событие.IDDOC=Журнал.IDDOC GROUP BY срм_Событие.Контрагент ) as пДокументы "); Запрос.ВыполнитьЗапрос(" SELECT Спр.ID as [Клиент :Справочник.Контрагенты] , пДокументы.Док as [Док :Документ.срм_Событие] FROM [Справочник.Контрагенты] Спр LEFT JOIN ПоследниеДокументы as пДокументы ON Спр.ID = пДокументы.Клиент "); Запрос.ВыполнитьЗапрос("DROP TABLE ПоследниеДокументы"); |
|||
53
Sam1C
19.02.18
✎
14:15
|
(46) Твой запрос похож с Djelf , но почему то лопатит час и заканчивается с ошибкой нехватки памяти. Не ужели это все из-за иннер джоин ?
select Спр.id [Клиентос:Справочник.Контрагенты] ,substr (Таб.МаксПозиция,-9) [Док:Документ.срм_Событие] from [Справочник.Контрагенты] Спр left join( select Док.шКонтрагент, max(idx_IDDOCDEF_DATE_TIME_IDDOC) МаксПозиция from Журнал Жур inner join [Документ.срм_Событие] Док WHERE Жур.IDDOCDEF=:ВидДокумента.срм_Событие group by Док.шКонтрагент) Таб on Таб.шКонтрагент=Спр.id |
|||
54
Sam1C
19.02.18
✎
14:16
|
(53) с WHERE Жур.IDDOCDEF=:ВидДокумента.срм_Событие и без нее без разницы
|
|||
55
Sam1C
19.02.18
✎
15:04
|
(51) Спасибо за свежую версию
|
|||
56
Ёпрст
19.02.18
✎
16:32
|
(53) это не мой код
|
|||
57
Ёпрст
19.02.18
✎
16:33
|
ёпт..
select Спр.id [Клиентос:Справочник.Контрагенты] ,right(Таб.МаксПозиция,9) [Док:Документ.срм_Событие] from [Справочник.Контрагенты] Спр left join( select Док.Контрагент, max(idx_IDDOCDEF_DATE_TIME_IDDOC) МаксПозиция from Журнал Жур inner join [Документ.срм_Событие] Док on Док.iddoc = Жур.iddoc group by Док.Контрагент) Таб on Таб.Контрагент=Спр.id |
|||
58
Ёпрст
19.02.18
✎
16:34
|
ну и right замени на
substr(Таб.МаксПозиция,-9,9) |
|||
59
Djelf
20.02.18
✎
20:17
|
Смысла в запросе в (52) особенно нет.
Смотрите план запроса в (29) explain`om. sqlite сам при выполнении создает внутренние временные таблицы , сам их индексирует и сам склеивает. Смысл в таком запросе может появится если переполняется память. Тогда да, придется создавать базу таблицу sqlite на диске, а не в памяти, но лучше выкручиваться как то по другому. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |