|
v7: Как склеить запросом несколько строк в одну, на примере таблицы 1SConst | ☑ | ||
---|---|---|---|---|
0
FobusVGrunt
01.06.16
✎
11:36
|
Строки > 23 в таблице 1SCons хранятся блоками, номер блока в колонке «PARTNO». Как в запросе выбрать все в одну строку, склеить:
OBJID| ID | DATE | PARTNO | VALUE 1 11T6 20160601 0 Привет 1 11T6 20160601 1 Как 1 11T6 20160601 2 дела? Получить в одну строку VALUE = «Привет как дела?», если это длинная строка. |
|||
1
Heckfy
01.06.16
✎
11:40
|
Никак.
|
|||
2
f_vadim
01.06.16
✎
11:45
|
||||
3
Heckfy
01.06.16
✎
11:50
|
(2) Это ни "Как". Это изврат. :)
|
|||
4
YurAnt
01.06.16
✎
11:58
|
была немного похожая задача, с тем отличием что значения были в трех разных колонках. Решал через пакет запросов.
т.е. к примеру по группировке ID=11T6 NULL NULL дела? Привет NULL NULL NULL как NULL Запросом 1 выбирал максимум по каждому столбцу затем Запросом 2 уже крутил вертел то что схлопнулось. Но у меня было жестко заданное кол-во записей в группировке |
|||
5
FobusVGrunt
01.06.16
✎
11:59
|
(2) Можно определять макс. число в поле PARTNO, и фигачить вложенные запросы к значение к полю,типа:
... ,((select ...Where PARTNO = 1) + (select ...Where PARTNO = 2)+... ) as VALUE FROM ..... Но не думаю, что нормальный подход с точки зрения производительности |
|||
6
Fragster
гуру
01.06.16
✎
12:00
|
т.е. склеить во встроенном языке вообще не вариант?
|
|||
7
FobusVGrunt
01.06.16
✎
12:02
|
(6) Почему вариант в ТаблицуЗначения загнать и перебрать её. Просто интересно стало в запросе можно ли
|
|||
8
FobusVGrunt
01.06.16
✎
12:11
|
Если такой вариант:
ТекстЗапроса = "Select |OBJID |,ID |,DATE |,CASE (select Max(PARTNO) FROM [_1S.Const] where id = t.ID and date = t.Date and objid = t.OBJID) |WHEN 0 THEN VALUE |WHEN 1 THEN VALUE + (select VALUE FROM [_1S.Const] where id = t.ID and date = t.Date and objid = t.OBJID and PARTNO = 1) |WHEN 2 THEN VALUE + (select VALUE FROM [_1S.Const] where id = t.ID and date = t.Date and objid = t.OBJID and PARTNO = 1) |+ (select VALUE FROM [_1S.Const] where id = t.ID and date = t.Date and objid = t.OBJID and PARTNO = 2) |... и т.д. |END AS [VALUE] |FROM [_1S.Const] as t |"; |
|||
9
FobusVGrunt
01.06.16
✎
12:11
|
(8) С точки зрения производительности?
|
|||
10
YurAnt
01.06.16
✎
12:13
|
кол-во PARTNO ограничено? или их может быть сколь угодно?
|
|||
11
FobusVGrunt
01.06.16
✎
12:14
|
(10) макс строка задать можно 999 символов, значит 999/23 = 43. Т.е. PARTNO ограниченно 43.
|
|||
12
FobusVGrunt
01.06.16
✎
12:17
|
(10) Но вообще можно узнать макс PARTNO по всей таблицы и динамически сформировать текст запроса.
|
|||
13
youalex
01.06.16
✎
12:22
|
DECLARE @s varchar(max) = ''
SELECT @s = @s + PARTNO FROM [_1S.Const] as t SELECT @s |
|||
14
YurAnt
01.06.16
✎
12:23
|
так или иначе вариант решения сводится к выборке строк в уже заготовленные колонки - с последующим сворачиванием в 1 строку.
суть думаю примерно та же что и в (8) Как вариант динамически собрать сам текст запроса. зашить добавление каждой колонки запроса в зависимости от кол-ва строк, и по итогу исполнить. это будет быстрее и производительнее нежели в цикле насиловать запросом базу построчно и собирать итоговую строку |
|||
15
YurAnt
01.06.16
✎
12:25
|
(14) хотя будет ли это быстрее чем решение в лоб: выбрать все и в цикле сформировать по результатам выборки строку... хз
|
|||
16
FobusVGrunt
01.06.16
✎
12:28
|
(8) А еще походу в этом запросе обязательно в конце:
|... FROM [_1S.Const] as t Добавить - where PARTNO = 0 так как PARTNO > 0 лопатить не надо, они вложенными выбираются. |
|||
17
FobusVGrunt
01.06.16
✎
13:07
|
Кому интересно по скорости запроса в (8), при MAX(PARTNO) = 4:
Время в милисекундах 1) Запрос в (8) -Время:2737, Кол строк:135911 2) Обычный запрос -"Select * FROM [_1S.Const]" - время:1924, Кол строк:165517 Т.е. всего на 42 % медленнее. Думаю запрос в (8)оптимальный. Дольше будет циклом перебирать ТЗ. |
|||
18
FobusVGrunt
01.06.16
✎
13:09
|
(8) Запрос на SQLIte, поэтому вместо "+", нужно "||" для склеивания строк. если стоит "+" или "&", возвращает "0". А то не мог понять в чем дело, выдавало 0.Может кому полезно будет эта инфа
|
|||
19
FobusVGrunt
01.06.16
✎
13:10
|
(13) Тут не совсем понятно, что имеется ввиду
|
|||
20
FobusVGrunt
01.06.16
✎
13:10
|
(1) Получается можно. а не "Никак"
|
|||
21
youalex
01.06.16
✎
14:07
|
(19) это для ms, на sqlite не взлетит. смысл в том, что к переменной @s - добавляется значение PARTNO каждой строки , получаемой в Select.
|
|||
22
Djelf
01.06.16
✎
14:33
|
А про GROUP_CONCAT забыли?
Ну у меня PARTNO почти нет чтобы проверить, но что-то склеивается....
|
|||
23
Ёпрст
01.06.16
✎
14:34
|
(18) для запроса на 1sйlite таким извратом не нужно заниматься вооообщееее, там поля неогр длины "читаются" из коробки, просто как поле в запросе.
А так, в 1sqlite есть еще group_concat, если чё |
|||
24
FobusVGrunt
01.06.16
✎
14:53
|
(23) Так в самой таблице ДБФ 1SConst, они лежат кусками
|
|||
25
FobusVGrunt
01.06.16
✎
14:53
|
(22) А что делает GROUP_CONCAT ?
|
|||
26
Djelf
01.06.16
✎
15:09
|
(25) Клеит ;)
Для sqlite GROUP_CONCAT(ЧтоСклеиваем,Разделитель=",") |
|||
27
FobusVGrunt
01.06.16
✎
15:19
|
(26) В моём случаи клеить надо VALUE, а не PARTNO и клеить надо с условиями, что бы полное совпадение строк (OBJID,ID,DATE), а PARTNO разные
|
|||
28
Djelf
01.06.16
✎
15:25
|
(27) ну в (22) только и осталось что поменять VALUE на PARTNO, это я очепятался...
|
|||
29
FobusVGrunt
01.06.16
✎
15:58
|
(28) я подставлял VALUE, не понимаю как она и что склеивает, но что работает в 3 раза дольше и результат не понятен мне, в моем запросе быстрее и все как надо. Но хотелось разобраться с GROUP_CONCAT. Что-то не получается с GROUP_CONCAT получить одну строку с колонками:
OBJID| ID | DATE | PARTNO | VALUE 1 11T6 20160601 0 Привет как дела как описано в (0) |
|||
30
AMKahm
01.06.16
✎
16:15
|
(29) ну так в (22) все есть, только нафиг PARTNO=0 нужен? его отбросить надо, или тоже в '0 1 2' клеить
SELECT OBJID,ID,DATE,GROUP_CONCAT(VALUE,' ') FROM (SELECT OBJID,ID,DATE,VALUE FROM 1SConst ORDER BY OBJID,ID,DATE,PARTNO ) GROUP OBJID,ID,DATE; |
|||
31
FobusVGrunt
01.06.16
✎
16:21
|
(30) PARTNO отбросить
|
|||
32
FobusVGrunt
01.06.16
✎
16:38
|
Всем спасибо разобрался GROUP_CONCAT, Выдает то что надо, но работает в 2,5 раза медленней, чем (8). Хотя конечно текст запроса в разы проще. Еще раз всем огромное спасибо
|
|||
33
Ёпрст
01.06.16
✎
16:51
|
(24) ну и что ?
|
|||
34
Mikeware
01.06.16
✎
16:52
|
(33) а как же лыжи, гамак...?
|
|||
35
ДенисЧ
01.06.16
✎
16:54
|
||||
36
FobusVGrunt
01.06.16
✎
16:58
|
(33) "там поля неогр длины "читаются" из коробки" не совсем понятно, что имеется ввиду.
|
|||
37
Ёпрст
01.06.16
✎
17:09
|
(36)
просто селект поле из справочник, например. Ну а в константах, так вообще не понятно, зачем там хранить такие значения. |
|||
38
Ёпрст
01.06.16
✎
17:10
|
периодика что ле ? Еще и неогр длины ?
|
|||
39
FobusVGrunt
01.06.16
✎
17:25
|
(38) Переодичку, не ограниченной длины нельзя задать. поле VALUE в 1SConst длиной 23, может и название организации быть > 23, вот оно и разбивает на блоки. мне надо запрос к этой таблице, а не через справочники вытягивать данные. Делаю выгрузку загрузку, решил что проще переодические реквизиты и константы загрузить одним махом, а не через справочники гонять
|
|||
40
Ёпрст
01.06.16
✎
17:40
|
(39) А откуда куда ?
|
|||
41
FobusVGrunt
01.06.16
✎
17:41
|
||||
42
Ёпрст
01.06.16
✎
17:44
|
(41) неудачное решение.
Как будешь пасти измененные объекты ? |
|||
43
FobusVGrunt
01.06.16
✎
17:51
|
(42) Задача измененных пасти нету. Эта пару переносов с одной базы в другую пустую с кое какими манипуляциями в новой в момент переноса. Пасти надо только новые объекты, для этого есть таблицы соответсвия по внутрений ID старой БД и новой в файле обмене (БД на SQLIte).
|
|||
44
FobusVGrunt
01.06.16
✎
17:58
|
(42) Почему не удачное решение, надо выгрузить данные куда-то и потом загрузить откуда-то. Можно это в текстовый файл выгрузить, но я выбрал формат БД Sqlite. По мне лучше чем строки разбирать
|
|||
45
FobusVGrunt
01.06.16
✎
18:05
|
(42) Да и при желании, можно и измененные объекты пасти. Перед следующей выгрузкой сравнивать, что лежит в БД Sqlite по реквизитам(полям) и помечать на обновление, если хоть один изменился, это на случай если понадобится, не лучший вариант, но повторюсь выгрузки одноразовые по разным клиентам с разными конфигурациями. Поэтому пасти изменения в старой БД например перехватчикомСобытий ни надо.
|
|||
46
Djelf
01.06.16
✎
23:02
|
Ну медленнее... ну и что? Да, там сначала упорядочивание, а потом группировка, а в твоем многоэтажном запросе подзапросы... Зато универсален. Запусти с максимальным количеством подзапросов 43 и будет уже не так весело.
Если хочется скорости можешь попробовать 1sqlite на движке 3.8.11.1 https://cloud.mail.ru/public/BRyV/g4MiSvgqz Сортировка и группировка там на b-tree, она примерно в 3 раза быстрее для этого конкретного случая. |
|||
47
FobusVGrunt
02.06.16
✎
08:49
|
(46) ок спасибо!
|
|||
48
Djelf
06.06.16
✎
17:51
|
Можно запрос и посложнее.
Всего раза в 2 медленнее чем без склейки длинных строк.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |