|
Подскажите по запросу SQL | ☑ | ||
---|---|---|---|---|
0
bublegum
29.11.13
✎
10:47
|
Есть запрос, для простоты вот такой, например:
SELECT table.text FROM table Нужно добавить вычисление длины самой длинной выбранной строки. Как это сделать лучше всего? Предполагаю, нужно использовать max( CHAR_LENGTH( table.text ) ) Но как это использовать в запросе? |
|||
1
КонецЦикла
29.11.13
✎
10:58
|
SELECT TOP 10 LEN(date_time_iddoc) AS Length
FROM _1sjourn (NOLOCK) |
|||
2
bublegum
29.11.13
✎
11:06
|
(1) Похоже твой вариант обрежет таблицу и выберет только TOP 10 записей, и остальные выбранные записи пропадут, придется второй выборкой их выбирать, а это наверное плохо.
|
|||
3
viktor_vv
29.11.13
✎
11:08
|
Так тебе надо выбрать одну строку с макисмальной длиной реквизита, или как ?
|
|||
4
КонецЦикла
29.11.13
✎
11:09
|
(2) SELECT Len(table.text)
FROM table Так пойдет? Написал Top на случай если кто-то полезет выполнять :) |
|||
5
viktor_vv
29.11.13
✎
11:11
|
Расшифруй на пальцах вот это
"вычисление длины самой длинной выбранной строки". |
|||
6
bublegum
29.11.13
✎
11:11
|
(3) мне надо добавить вычисление самой длинной строки в существующий запрос, при этом не портя этот запрос. Изначально запрос выбирает много строк.
|
|||
7
Ненавижу 1С
гуру
29.11.13
✎
11:12
|
(6) что на выходе то должно быть?
|
|||
8
viktor_vv
29.11.13
✎
11:12
|
(6) В каком виде нужен результат вычисления "Самой длиной строки" ?
|
|||
9
КонецЦикла
29.11.13
✎
11:14
|
А сорри, ну тогда так пойдет?
SELECT Max(LEN(Text)) AS Length FROM Table(NOLOCK) |
|||
10
bublegum
29.11.13
✎
11:15
|
(5) предположим запрос дает такой результат:
table.text: "вавыы" "йцуйц кйцкйц" "выывпы" А мне нужно чтобы он еще вычислил длину строк, определил самую длинную, и выдал это число хоть как-нибудь, например в отдельной колонке: table.text, table.length "вавыы", 12 "йцуйц кйцкйц", 12 "выывпы", 12 |
|||
11
bublegum
29.11.13
✎
11:16
|
(9) так вообще выберется всего одна строка.
|
|||
12
КонецЦикла
29.11.13
✎
11:19
|
Ясно. Через 10 постов.
Так пойдет? SELECT Text, LEN(Text) AS Length FROM Table(NOLOCK) order by LEN(Text) Desc |
|||
13
toypaul
гуру
29.11.13
✎
11:20
|
(12) как я понял - надо в каждой строке макс длину по всей таблице
|
|||
14
КонецЦикла
29.11.13
✎
11:20
|
Я пока отчаливаю...
|
|||
15
toypaul
гуру
29.11.13
✎
11:21
|
что-то типа этого
select t.f,l.l from t,(select max(len(t.f)) l from t) l |
|||
16
bublegum
29.11.13
✎
11:22
|
(12) нет, так ты испортил всю сортировку в таблице тем что вставил order by LEN(Text) Desc
|
|||
17
bublegum
29.11.13
✎
11:23
|
(15) то есть два раза делать выборку по таблице. Не красиво как-то...
|
|||
18
toypaul
гуру
29.11.13
✎
11:24
|
(17) сделай красиво
|
|||
19
Ёпрст
29.11.13
✎
11:30
|
(17) ежели скуль >=2008 то пользуй over
|
|||
20
Ёпрст
29.11.13
✎
11:30
|
там будет красиво и одним запросом
|
|||
21
viktor_vv
29.11.13
✎
11:30
|
(17) Зато логично :).
|
|||
22
Ёпрст
29.11.13
✎
11:31
|
только не помню, был ли over в 2005..
|
|||
23
КонецЦикла
29.11.13
✎
11:39
|
(16) Ой...
А может ты подключишься к обсуждению хотя бы живым понятным примером наподобие (10)? |
|||
24
bublegum
29.11.13
✎
11:40
|
over похоже нет. У меня вообще MySQL
(23) а чем пример из (10) не подходит? |
|||
25
Ёпрст
29.11.13
✎
11:42
|
в MySQL не в курсе, есть ли там ранжирующие функции
|
|||
26
bublegum
29.11.13
✎
11:42
|
Наверное лучше всего использовать временную таблицу, поместить в нее всю выборку, а потом уже во временной таблице считать максимальную длину строки.
|
|||
27
Ёпрст
29.11.13
✎
11:44
|
тогда так
select t.f,(select max(len(f)) from t (nolock)) from t (nolock) |
|||
28
Ёпрст
29.11.13
✎
11:45
|
Коррелированный подзапрос будет выполнятся 1 раз, если че..
|
|||
29
IVT_2009
29.11.13
✎
11:46
|
SELECT len(str) AS ln FROM table ORDER BY ln DESC LIMIT 10
|
|||
30
IVT_2009
29.11.13
✎
11:47
|
удаляет по ID где менее 10 записей
DELETE FROM coord WHERE id in(SELECT id FROM (SELECT id,count(id) as dd FROM coord GROUP BY id ) WHERE dd<10); |
|||
31
toypaul
гуру
29.11.13
✎
11:50
|
(17) вообще головой надо думать. как можно за один проход получить серверу нужный результат? всеравно первой выборкой обходим все строки чтобы определить максимум, второй выборокой получаем результат.
если исходная таблица это сложный запрос, то конечно лучше его во врем таблицу скинуть. |
|||
32
КонецЦикла
29.11.13
✎
11:50
|
(26) А потом делать селект из временной таблицы? См (28)
|
|||
33
bublegum
29.11.13
✎
11:51
|
(27) это же все равно два запроса. разве нет?
|
|||
34
КонецЦикла
29.11.13
✎
11:51
|
(33) Храни где-нибудь максимальную длину, делов-то
|
|||
35
bublegum
29.11.13
✎
11:52
|
получается запрос + подзапрос, запрос выбирает все данные, подзапрос выбирает те же самые данные + находит длину самой длинной строки
|
|||
36
Ёпрст
29.11.13
✎
11:53
|
(33) и че ?
|
|||
37
Ёпрст
29.11.13
✎
11:53
|
ты разницу в скорости для миллиона записей даже не заметишь
|
|||
38
dk
29.11.13
✎
11:54
|
(27) +1
|
|||
39
bublegum
29.11.13
✎
11:54
|
(36) не красиво же.
|
|||
40
madyka
29.11.13
✎
11:54
|
declare
@MaxLen Int; Set @MaxLen = (Select max(len(t.text)) from table as t(nolock)) Select t.text as Str, @MaxLen as MaxLen from table (nolock) |
|||
41
КонецЦикла
29.11.13
✎
11:54
|
1С делает также некоторые вещи, подзапросом
Так что тебе тоже можно |
|||
42
IVT_2009
29.11.13
✎
11:55
|
(40) красиво ms sql умеет
|
|||
43
bublegum
29.11.13
✎
11:56
|
(34) например где ее хранить? Думаю было бы оптимально пробежаться по таблице во время выборки данных один раз, считать длину текущей строки, сравнивать ее с максимальной, и если она больше, то далее считать ее максимальной. И чтобы результат получился такой:
table.text, table.length "вавыы", 5 "йцуйц кйцкйц", 12 "выывпы", 12 тогда я буду знать что в последней строке находится нужный результат. |
|||
44
bublegum
29.11.13
✎
11:58
|
(40) тоже два раза выбираются данные
|
|||
45
КонецЦикла
29.11.13
✎
11:59
|
(43) Триггер навесь и храни где-нибудь
Если выборка выполняется миллион раз в день то будет оправданно |
|||
46
madyka
29.11.13
✎
11:59
|
(37)
записей 175 млн строк. один запрос с выражением потребует группировку. Опять же лишнее... Так что только с подзапросом - вычислить макс длину. И вставлять куда нужно |
|||
47
bublegum
29.11.13
✎
11:59
|
(43) Это я знаю как сделать только в цикле, когда уже данные выбраны. Как заставить это сделать запросом я не знаю (((
|
|||
48
madyka
29.11.13
✎
12:00
|
(44)
Чем те не нравится 2 раза? |
|||
49
КонецЦикла
29.11.13
✎
12:01
|
(47) Триггер который будет сравнивать длину вставляемой/редактируемой строки и хранимую где-нибудь длину (сам выбери базу и таблицу создай). Вот и все.
|
|||
50
bublegum
29.11.13
✎
12:01
|
(48) Думаю что 1 раз лучше чем 2. Более логично. Данные и условия абсолютно одинаковые выбираются, зачем два раза их выбирать?
|
|||
51
bublegum
29.11.13
✎
12:02
|
(49) условия выборки каждый раз разные. Я упростил запрос только для примера, чтобы не пугались.
|
|||
52
madyka
29.11.13
✎
12:04
|
(50)
Не всегда. Если же тебе постоянно надо знать актуальное значение максимального значения длины строки - то советую триггер. Будет быстрее использоваться в дальнейшем, особенно если к-во строк в таблице на десятки сотни млн строк. А если колонка текстовая длиной в 100 букв и больше - то тем более. |
|||
53
madyka
29.11.13
✎
12:05
|
(0) - (49) уже писал
|
|||
54
madyka
29.11.13
✎
12:05
|
"Логично" - не всегда самый короткий и быстрый путь
|
|||
55
madyka
29.11.13
✎
12:07
|
Вот у мну запрос с выражением занял 4 мин, и вариант с двумя запросами - 2 мин.
|
|||
56
madyka
29.11.13
✎
12:12
|
Причем, если колонка, по которой идет подсчет макс длины, типа char - то придется добавить RTRIM (отсечь правые пробелы), иначе макс длина будет равна длине строки колонки
|
|||
57
madyka
29.11.13
✎
12:13
|
а строковые операции довольно тормозят.
ТАк что настоятельно рекомендую, как другие говорили - триггер и хранить макс длину в любом месте базы. Эти при условии частого использования этой величины. |
|||
58
КонецЦикла
29.11.13
✎
12:18
|
(56) у тебя SQL какой-то неправильный, не нужно отсекать
|
|||
59
Jaap Vduul
29.11.13
✎
12:20
|
(43)
Насколько помню, в mysql можно так: set @max=0; select table.text, @max:=IF(CHAR_LENGTH(table.text)>@max,CHAR_LENGTH(table.text),@max) from table |
|||
60
bublegum
29.11.13
✎
12:26
|
(59) о, супер! Если так можно...
|
|||
61
КонецЦикла
29.11.13
✎
12:28
|
(60) Все равно это скан таблицы, посмотри планы выполнения
Чудес не бывает Храни значение если его нужно получать быстро |
|||
62
madyka
29.11.13
✎
12:31
|
(59) - выражение вычисляется походу 2 раза
И максимальное значение будет не во всех строках, а к концу таблицы. Не оч хорошо. |
|||
63
GANR
29.11.13
✎
12:31
|
(0) Рассмотрим несколько возможных ситуаций:
1. Если дело на МС СКЛ 2012 select a.text, max(len(a.text)) over() max_len from table a 2. Если более молодая версия - запросик будет малость посложнее select a.text, b.max_len from table a, (select max(len(a.text)) max_len from table a) b 3. Если непонятно вышесказанное в этом сообщении - идем сюда http://www.sql-ex.ru/. |
|||
64
bublegum
29.11.13
✎
12:32
|
Все понятно, только (59) пока лучше всех
|
|||
65
Ёпрст
29.11.13
✎
12:33
|
(63) over есть и на 2008, у автора - мускул..
|
|||
66
Ёпрст
29.11.13
✎
12:34
|
(64) чем ?
Ты хоть ЭТО проверил ? :)) |
|||
67
madyka
29.11.13
✎
12:35
|
(64) - ты попробуй блин сначала на сервере, а потом уже говори у кого лучше :)
Опять же повторюсь - если таблица в десятки млн строк - то как ни крути - запрос будет "думать"... |
|||
68
КонецЦикла
29.11.13
✎
12:36
|
(66) Да, автор похож на упоротого "начальнега"
|
|||
69
GANR
29.11.13
✎
12:38
|
(64) А что именно лучше - ответит план запроса.
(65) Нееет - с 2005 были ранжирующие функции, а вот в 2012-м появились именно оконные - это немного разные вещи http://www.sql-tutorial.ru/ru/book_window_functions.html http://www.sql-tutorial.ru/ru/book_running_totals/page2.html. |
|||
70
bublegum
29.11.13
✎
12:40
|
(66) тем что ничего лишнего не выбирается.
|
|||
71
bublegum
29.11.13
✎
12:40
|
(67) На сервере работает отлично
|
|||
72
GANR
29.11.13
✎
12:43
|
А как такая версия для мускула?
select a.name, b.max_len from ships a, (select max(char_len(a.name)) max_len from ships a) b |
|||
73
GANR
29.11.13
✎
12:46
|
select a.text, b.max_len from
table a, (select max(char_len(a.text)) max_len from table a) b |
|||
74
Ёпрст
29.11.13
✎
12:46
|
(69) нифига, с 2008
|
|||
75
madyka
29.11.13
✎
12:48
|
(58)
Гм, каюсь, ты прав - отсекать пробелы предварительно не нужно, len пробелы не учитывает справа ) |
|||
76
GANR
29.11.13
✎
12:48
|
||||
77
madyka
29.11.13
✎
12:49
|
(71)
Опробуй несколько запросов, и только после этого делай выводы. Кому хорошо - другому смерть. |
|||
78
GANR
29.11.13
✎
12:49
|
(76) к (74)
|
|||
79
GANR
29.11.13
✎
12:53
|
+(76)(74) Ах воооон как - точно, это было до 2012, только без секции order by, что не позволяло именно накопительный итог считать.
|
|||
80
Ёпрст
29.11.13
✎
12:59
|
(76) ну и че ты 2005 подсовываешь ?
Я грю за 2008 |
|||
81
Ёпрст
29.11.13
✎
12:59
|
(79) в 2008 позволяло.
|
|||
82
Ёпрст
29.11.13
✎
13:01
|
посмотри примеры с мах, мин, суммой.. для каждой строки..
|
|||
83
GANR
29.11.13
✎
13:36
|
(81) И в 2005 и в 2008 была секция PARTITION BY для (82), а вот в 2012 появилась еще и секция ORDER BY для оконных функций http://msdn.microsoft.com/ru-ru/library/ms189461(v=sql.100).aspx - вот она и позволила считать накопительные итоги (не по этой задаче).
|
|||
84
GANR
29.11.13
✎
13:37
|
||||
85
КонецЦикла
29.11.13
✎
13:41
|
Епать, целый диспут развернулся
|
|||
86
Ёпрст
29.11.13
✎
13:56
|
(83) ты про фифо прям в запросе что ле ?..
|
|||
87
Ёпрст
29.11.13
✎
13:57
|
надо будет посмотреть..
|
|||
88
GANR
29.11.13
✎
13:58
|
(86) И это в частности.
|
|||
89
GANR
29.11.13
✎
14:00
|
+(88) Но если (86) делать 1С-овским запросом - эдак, имхо, сервер уронить можно.
|
|||
90
Sorm
29.11.13
✎
14:24
|
(89) Надо будет посмотреть, во что транслируется фифо из 1с, я делал в скуле прямо - все чисто, красиво.
|
|||
91
GANR
29.11.13
✎
15:30
|
(90) Оконные функции и функции ранжирования нельзя использовать на уровне 1С-запросов - вот и подумай после этого что будет в скуле.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |