Имя: Пароль:
IT
 
Задачка: запрос & перестановки
,
0 andrewks
 
23.11.11
21:23
дано: 1с-диалект sql, ВТ разрешены.
есть одномерная ВТ tt1 с полем val разрядности N, представляющая собой множество X (пусть, например, это будут натуральные числа)

результатом нужно получить множество перестановок элементов множества X

в случае, когда N заранее известно, всё понятно, декартово с условиями. а как быть, если N заранее неизвестно? можно ли построить универсальный запрос для данного случая?
1 Креатив
 
23.11.11
21:24
(0)Что?
2 Ёпрст
 
23.11.11
21:25
можно
cross join
3 andrewks
 
23.11.11
21:25
(1) где?
4 andrewks
 
23.11.11
21:26
(2) в 1с разве есть такое?
5 Rie
 
23.11.11
21:26
(0) То, что факториал быстро растёт - тебя не смущает?
6 andrewks
 
23.11.11
21:27
(5) нет. задачка не прикладная
7 Ёпрст
 
23.11.11
21:27
(4) ты не поверишь!
:)
8 andrewks
 
23.11.11
21:29
(7) тьху, извиняюсь, протупил. я ж про декратово и говорил


однако: N - неизвестно!
9 andrewks
 
23.11.11
21:31
во избежание недоразумений уточню:
под "1с-диалект sql" я подразумеваю язык запросов 1с v8
10 rs_trade
 
23.11.11
21:34
(9) можно пример таблички со значениями? в сабже слова все знакомые, но чего надо так и не понял.
11 andrewks
 
23.11.11
21:36
(10) ну, допустим, мы знаем, что N = 5

тогда мы можем составить такой запрос:


select
1 as val
into tt1
union select 2 union select 3 union select 4 union select 5

;

select
tt1.val as val1
,tt2.val as val2
,tt3.val as val3
,tt4.val as val4
,tt5.val as val5
from
tt1
,tt1 as tt2
,tt1 as tt3
,tt1 as tt4
,tt1 as tt5
where (tt1.val<>tt2.val) and (tt1.val<>tt3.val) and (tt1.val<>tt4.val) and (tt1.val<>tt5.val)
 and (tt2.val<>tt3.val) and (tt2.val<>tt4.val) and (tt2.val<>tt5.val)
 and (tt3.val<>tt4.val) and (tt3.val<>tt5.val)
 and (tt4.val<>tt5.val)


но для другой разрядности множества он уже не сгодится
12 Rie
 
23.11.11
21:38
(11) А не дал ли ты тем самым ответ на свой вопрос о существовании универсального запроса?
13 andrewks
 
23.11.11
21:39
(12) т.е. твой вердикт отрицательный?
14 Rie
 
23.11.11
21:40
(13) У тебя по синтаксису SQL в select должны торчать все колонки. А их у тебя - переменное число N.
15 rs_trade
 
23.11.11
21:45
ну как минимум можно текст запроса составлять по значению N ))
16 Rie
 
23.11.11
21:53
(15) Тогда в (11) было бы решение. Но раз ТС говорит "не сгодится" - значит, нельзя.
17 rs_trade
 
23.11.11
21:54
(16) он не думал в это время о динамическом sql.
18 andrewks
 
23.11.11
21:59
(17) не-не-не, никаких сферических коней. попробую ещё раз объяснить, по-другому.

представь, что перед тобой консоль запросов, и дан справочник X с заранее неизвестным числом элементов. тебе нужно вписать текст запроса, чтобы он, независимо от поступишего содержимого этого справочника, выдал мн-во перестановок эл-тов этого справочника
19 Rie
 
23.11.11
22:09
(18) Ну так ты и натыкаешься на то, что количество колонок в select - фиксировано.

Однако возникает вопрос - а как представлена перестановка в таблице? Тут ведь возможны варианты. Например, можно запихнуть их все в таблицу с тремя колонками
НомерПерестановки НомерЭлементаВПерестановке Элемент
20 Rie
 
23.11.11
22:10
+(19) (Но легче от изменения представления не станет. IMHO)
21 andrewks
 
23.11.11
22:10
(19) мы начинаем выходить на правильную дорогу :)
22 andrewks
 
23.11.11
22:11
(20) ну почему же. мы избавились от технический неразрешимости. осталась логика
23 andrewks
 
23.11.11
22:16
(19) только структурно правильнее будет, наверное, так:
НомерПерестановки  Перестановка(влож. таблица с НомерЭлементаВПерестановке ЭлементМножества)
24 rs_trade
 
23.11.11
22:17
по моему язык запросов 1с слишком убог для таких задач
25 Rie
 
23.11.11
22:18
(23) "Предполагая декартово произведение ассоциативным, а таблицы - находящимися в 1НФ..." - по барабану :-)
26 andrewks
 
23.11.11
22:19
(24) в этом вся соль ;-)
27 Rie
 
23.11.11
22:19
(25) "ассоциативным" <- "ассоциативным и коммутативным"

На самом деле (23) неприятно тем, что отбросит алгоритмы, в которых номер перестановки будет существенно использоваться для её порождения.
28 Визард
 
23.11.11
22:20
(0) cross join  не подходит?
29 andrewks
 
23.11.11
22:21
(25) это будет больше соответствовать условиям: в результате будут именно перестановки, а не их части.
(27) но для "лиха беда начало" можно пока и не заморачиваться с (23)
30 Rie
 
23.11.11
22:23
(29) А вот после того, как построишь - группируй, как тебе угодно.

Сможешь на 1СQL построить начальный отрезок натурального ряда? Ой, вряд ли :-)
Ну а стало быть, и о перестановках не мечтай.
31 andrewks
 
23.11.11
22:27
(30) "Сможешь на 1СQL построить начальный отрезок натурального ряда?"

ты про это?

select
0 as val
into tt1
union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9

;

select
tab1.val+1+10*tab2.val+100*tab3.val as val
into num_tab
from
tt1 as tab1, tt1 as tab2, tt1 as tab3
where (tab1.val+1+10*tab2.val+100*tab3.val<=&Размерность)
index by val
32 Визард
 
23.11.11
22:29
(31) че нужно получить?
33 Rie
 
23.11.11
22:30
(31) Не годится. Произвольный отрезок так не соорудишь.

Теперь о перестановках.
Любой из реляционных операторов даёт таблицу размером не более чем произведение размеров исходных таблиц.
Факториал же растёт быстрее любого полинома.
34 andrewks
 
23.11.11
22:30
(32) все условия - в (0)

нужен ответ на вопрос, возможно ли построение универсального текста запроса для решения этой задачи. и, если да, то похвастаться этим текстом :)
35 rs_trade
 
23.11.11
22:31
(34) только динамическим текстом запроса.
36 andrewks
 
23.11.11
22:32
(33) что значит "произвольный" в твоём понимании?

на крайняк, можно договориться, например, что N<MAX_N, задаваемого в параметрах
37 Rie
 
23.11.11
22:37
(36) Если "можно договориться" - то в (11) решение твоей задачи.

В противном случае в (33) - математически строгое доказательство того, что запроса, решающий задачу (0) - не существует.
38 andrewks
 
23.11.11
22:38
(37) нет. условия "на входе мн-во размерности не более 1000", и "на входе мн-во размерности 100"  - это две большие разницы
39 Rie
 
23.11.11
22:41
(38) Нет разницы.
Строишь решение для 1000 (это и будет твой универсальный запрос) - а потом обрезаешь лишнее при помощи where.

Если же никакого MAX_N не предусмотрено, то задача из (0) - неразрешима.
40 andrewks
 
23.11.11
22:41
+(38) *мощности
41 Rie
 
23.11.11
22:43
(40) Я так и понял. Всё равно (39).
42 andrewks
 
23.11.11
22:47
(39) хорошо, что-то мы заговорились не туда. неправильно.
я имел в виду именно так, пусть N<MAX_N, задаваемого в параметрах.
т.е. при написании запроса мы не знаем, что там - в MAX_N, но знаем, что оно, вероятно, может быть достаточно велико, чтобы (39) не прокатило

эту договорённость можно считать сугубо в угоду незагромождения памяти сверхбольшими таблицами, т.к. всё равно понятно, что при прикладном решении  размерность всё равно ограничена физическими параметрами ЭВМ.
43 Rie
 
23.11.11
22:52
(42) Всё равно от (33) ты никуда не денешься. Факториал обгонит любой полином.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой