powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Волшебство с помощью чистого SELECTA-а.
25 сообщений из 26, страница 1 из 2
Волшебство с помощью чистого SELECTA-а.
    #37129363
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Есть задача:

1. Дана таблица T (какая СУБД не имеет значения).
2. В таблице есть 1 столбец с названием ID.
3. В таблице располагается натуральная, возрастающая последовательность с "пропусками".


Использую СУБД MySQL 5.0.

Нужно:
Написать один select - запрос, который бы вывел все числа из каждого "пропуска" последовательности.
Например:
Последовательность: 1,2,3,7,8,9,11,20,....
Решение: 4,5,6,10,12,13,14,15,16,17,18,19,...

Каждое число последовательности это запись в столбике T.ID.

То есть SELECT - запрос должен вывести те числа, которые нужно вставить в последовательность, чтобы получить ряд натуральных чисел. Как это сделать? Интересно с помощью чего это можно сделать если даже забыть про один select - запрос.

P. S. Я так понял один select - запрос - это отсутствие соотнесённых под запросов.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37129377
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhY,

получить в виде резалт сета из N строк, где N - количество пропусков одним SELECTом для любого количества пропусков не получится. Получить в виде резалт сета из одной строки и одной колонки с разделенными некоторым символом(ами) пропусками - получится.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37129668
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhY(какая СУБД не имеет значения)Имхо, либо нужно иметь физическую опорную таблицу (содержащую все возможные значения ID), либо решение будет СУБД-зависимым. Т.е. вам нужно определиться, что для вас более приемлемо.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130295
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftИмхо, либо нужно иметь физическую опорную таблицу (содержащую все возможные значения ID), либо решение будет СУБД-зависимым. Т.е. вам нужно определиться, что для вас более приемлемо.
Я надеюсь, что (какая СУБД не имеет значения) - это не призыв к использованию стандарта SQL, а предоставление выбора СУБД мне, хотя может быть это и не так. А вот добавлять ещё одну таблицу со всеми возможными значениями ID - нельзя. Если б можно было добавить табл. AllPossible в столбику ID которого хранились бы все возможные значения ряда: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20 ..., то задача решалась бы так:
SELECT AllPossible.ID
FROM T RIGHT JOIN AllPossible ON T.ID=AllPossible.ID
WHERE T.ID IS NULL;

Это дало бы требуемый результат: 4,5,6,10,12,13,14,15,16,17,18,19,... НО нет у нас опорной таблицы. Поэтому подскажите пожалуйста СУБД зависимое решение. Хоть для какой нибудь СУБД, можно для MySQL.

Поэтому изменю шапку задачи:
1. Дана таблица T (можно использовать любую СУБД).
2. В таблице есть 1 столбец с названием ID.
3. В таблице располагается натуральная, возрастающая последовательность с "пропусками".


an0nymПолучить в виде резалт сета из N строк, где N - количество пропусков одним SELECTом для любого количества пропусков не получится. Получить в виде резалт сета из одной строки и одной колонки с разделенными некоторым символом(ами) пропусками - получится..
Спасибо за такой уточненный ответ. Потому что я не знаю как это можно сделать, а Вы знаете что этого сделать нельзя. Отсутствие решения тоже решение, а может быть лучшее из них. Вбивать в одну строку через пробелы (разделители) последовательность я думаю нельзя, но если бы можно было подскажите каким образом выдрать пропущенные (недостающие) элементы натурального ряда .

P.S. Спасибо что не оставляли комментариев про тупость использования БД для хранения такого рода информации, потому что это ОЧЕВИДНО тупо, но может пригодится.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130418
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhYmiksoftИмхо, либо нужно иметь физическую опорную таблицу (содержащую все возможные значения ID), либо решение будет СУБД-зависимым. Т.е. вам нужно определиться, что для вас более приемлемо.
Я надеюсь, что (какая СУБД не имеет значения) - это не призыв к использованию стандарта SQL, а предоставление выбора СУБД мне, хотя может быть это и не так.Ну это уже вам решать. ArhYА вот добавлять ещё одну таблицу со всеми возможными значениями ID - нельзя. Если б можно было добавить табл. AllPossible в столбику ID которого хранились бы все возможные значения ряда: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20 ..., то задача решалась бы так:
SELECT AllPossible.ID
FROM T RIGHT JOIN AllPossible ON T.ID=AllPossible.ID
WHERE T.ID IS NULL;

Это дало бы требуемый результат: 4,5,6,10,12,13,14,15,16,17,18,19,... НО нет у нас опорной таблицы. Поэтому подскажите пожалуйста СУБД зависимое решение. Хоть для какой нибудь СУБД, можно для MySQL.

Поэтому изменю шапку задачи:
1. Дана таблица T (можно использовать любую СУБД).
2. В таблице есть 1 столбец с названием ID.
3. В таблице располагается натуральная, возрастающая последовательность с "пропусками".
Все способы, которые мне приходят в голову, собственно, сводятся к уже предложенному вами запросу. Только опорная таблица берется не реально существующая, а генерится "виртуальная". Вот этот способ генерации "вирутальной" таблицы и различается в разных СУБД.
Можно сделать так:
1) Взять любую таблицу, где гарантированно достаточно записей. Если готовой нет, то взять любую и помножить ее саму на себя два или более раз.
2) пронумеровать записи в "виртуальной" таблице из пункта 1. В случае с MySQL нумерация делается переменными, см. FAQ: Нумерация строк и другие вопросы про использование переменных .
3) подставить конструкцию из пункта 2 в ваш вариант запроса вместо AllPossible.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130438
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhYСпасибо за такой уточненный ответ. Потому что я не знаю как это можно сделать, а Вы знаете что этого сделать нельзя. Отсутствие решения тоже решение, а может быть лучшее из них. Вбивать в одну строку через пробелы (разделители) последовательность я думаю нельзя, но если бы можно было подскажите каким образом выдрать пропущенные (недостающие) элементы натурального ряда .
Вы немного не поняли. На входе будет таблица из множества строк, содержащих идентификаторы, с пропусками, а на выходе резалт сет из одной строки одной колонки, содержащий перечисление пропусков через запятую (или другой разделитель). Если такой способ подойдет, то я знаю специфичное решение на диалекте MySQL.

Остальные способы реализуются как объяснил miksoft и ограничения накладываются именно в части возможности генерации нужного набора строк без изменения структуры запроса. В MySQL это сделать нельзя. В Oracle можно. В MS SQL можно. В Postgres не знаю.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130441
qwerty112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130693
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwerty112,

на большой таблице в MySQL запрос повесится.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130710
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an0nymqwerty112,

на большой таблице в MySQL запрос повесится.Да и, строго говоря, там запрос не для этой задачи. А если приводить к этой, то опять придем к опорной таблице.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37130746
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an0nymОстальные способы реализуются как объяснил miksoft и ограничения накладываются именно в части возможности генерации нужного набора строк без изменения структуры запроса. В MySQL это сделать нельзя. В Oracle можно. В MS SQL можно. В Postgres не знаю .Там есть generate_series, т.е. тоже можно.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131258
qwerty112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftan0nymqwerty112,

на большой таблице в MySQL запрос повесится.Да и, строго говоря, там запрос не для этой задачи. А если приводить к этой, то опять придем к опорной таблице .
ну в общем - так и есть,

разве что можно обойтись без таблицы, а "крутить" что-то типа этого
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
select cast(num as SIGNED) as n from (
select concat(a.dig, b.dig) as num 
  from 
(select '0' as dig
  union all 
 select '1'
  union all
select '2'
  union all
select '3'
  union all
select '4'
  union all
select '5'
  union all
select '6'
  union all
select '7'
  union all
select '9'
  union all
select '9') a,
(select '0' as dig
  union all 
select '1'
  union all
select '2'
  union all
select '3'
  union all
select '4'
  union all
select '5'
  union all
select '6'
  union all
select '7'
  union all
select '9'
  union all
select '9') b) c
отсюда - 5414410
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131288
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwerty112,

а теперь сделайте тоже самое для значений <=999; <=9999 и т. д. Об этом всю тему и рассказывают.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131431
qwerty112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
an0nymqwerty112,

а теперь сделайте тоже самое для значений <=999; <=9999 и т. д. Об этом всю тему и рассказывают.

вот сразу видно, что Вы практик )))

а ТС, даже не заморачивается указанием/выбором конкретной СУБД, не то что "скорострельностью" -
an0nymна большой таблице в MySQL запрос повесится
но и, тем более, эстетической красотой ))

интиресует простой/банальный вопрос - "можно ли это сделать одним селектом" ?
ArhY Нужно:
Написать один select - запрос, который бы вывел все числа из каждого "пропуска" последовательности.

я правда не знаю, что он имел ввиду под "соотнесённых под запросов"
ArhYP. S. Я так понял один select - запрос - это отсутствие соотнесённых под запросов.
соотнесённых - это кореллированных ??

но если дерив.тейбл - под это ограничение НЕ попадают,
то я бы ответил, что
При определённом ограничении
а) макс.номер ИД - НЕ более чем столькото (чуть проще)
или
б) макс. величина "дырки" между ИД - НЕ более чем столькото (чуть сложнее)
- это вполне возможно


и плевать на сложность/время выполнения - главное, что такая возможность есть
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131450
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftМожно сделать так:
1) Взять любую таблицу, где гарантированно достаточно записей. Если готовой нет, то взять любую и помножить ее саму на себя два или более раз.
2) пронумеровать записи в "виртуальной" таблице из пункта 1. В случае с MySQL нумерация делается переменными, см. FAQ: Нумерация строк и другие вопросы про использование переменных .
3) подставить конструкцию из пункта 2 в ваш вариант запроса вместо AllPossible.

Сделал так (работает, хоть и не всегда):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT AllPossible.ID
FROM T RIGHT JOIN (
    SELECT @i:=@i+ 1  AS ID
    FROM T, T Self, (SELECT @i:= 0 ) AS Z
) AS AllPossible ON T.ID=AllPossible.ID
WHERE T.ID IS NULL AND AllPossible.ID <= (
    SELECT MAX(T.ID)
    FROM T
);
Почему не всегда? Потому что, как сказал miksoft , надо брать любую таблицу, где гарантированно достаточно записей.

А теперь для тех, кто первый раз читает эту тему (по пунктам от miksoft ):
1) Поскольку кроме табл. Т других таблиц нет, то будем использовать именно её. На хранящееся в ней (в базе) данные это не повлияет. Помножить таблицу (множество, англ. set) значит найти "декартово произведение" этой таблицы (множества) с другой табл. (множеством). Я помножил табл. T саму на себя так:
Код: plaintext
FROM T, T Self
Можно это сделать так:
Код: plaintext
FROM T CROSS JOIN T Self
.
Псевдоним Self нужен из-за одинаковых имён таблиц (имена одинаковые поскольку мы умножаем T на T).
Поэтому нельзя быть уверенным , что TхT будет содержать достаточно записей. Например:
Если выходная таблица состоит из двух записей: 1, 100, то результатом запроса должна быть последовательность: 2, 3, 4, 5, 6, ..., 95, 96, 97, 98, 99. Но TxT будет содержать всего 4 записи. Не хватает.

Если TxT содержит чересчур много записей, то убираем лишние вот так:
Код: plaintext
1.
2.
3.
WHERE ... AND AllPossible.ID <= (
    SELECT MAX(T.ID)
    FROM T
);

2) Пронумеруем записи в виртуальной таблице TxT (см. ссылку в посте miksoft ):
Код: plaintext
1.
SELECT @i:=@i+ 1  AS ID
FROM T, T Self, (SELECT @i:= 0 ) AS Z

3) Подставляем, это всё в мой вариант и получим запрос, который приведён в начале этого поста.

P. S. Это работает для примера, который приведён вначале темы. В каждом конкретном случае, нужно смотреть во сколько раз помножить табл. Т: ТхТ, ТхТхТ, ТхТхТхТ и т. д. Имхо, задача не стандартна и решение тоже. Это работает. Спасибо miksoft .
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131469
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhY,

я бы не стал трогать базовую таблицу - дешевле системную.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT t1.id
FROM t
  RIGHT JOIN (
    SELECT ti.id
    FROM (
        SELECT @rownum := @rownum +  1  id
        FROM (SELECT @rownum :=  0  rownum) v,
          (SELECT null UNION ALL SELECT null) tii1,
          (SELECT null UNION ALL SELECT null) tii2,
          ...
          (SELECT null UNION ALL SELECT null) tiiM
      ) ti
    WHERE ti.id <= N
  ) t1 ON t.id = t1.id
WHERE t.id IS NULL
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131474
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwerty112я правда не знаю, что он имел ввиду под "соотнесённых под запросов"ArhYP. S. Я так понял один select - запрос - это отсутствие соотнесённых под запросов.
Имел ввиду такого вида: СООТНЕСЕННЫЕ ПОДЗАПРОСЫ .

Как видите из предыдущего моего поста - я забил на один select - запрос и какая СУБД не имеет значения . Использовал подзапросы и переменные в MySQL. Потому что an0nym написал, что первоначальное задание вообще не реально выполнить.an0nymполучить в виде резалт сета из N строк, где N - количество пропусков одним SELECTом для любого количества пропусков не получится.

an0nym подскажите пожалуйста каким образом и с помощью каких особенностей диалекта MySQL.
an0nymArhYСпасибо за такой уточненный ответ. Потому что я не знаю как это можно сделать, а Вы знаете что этого сделать нельзя. Отсутствие решения тоже решение, а может быть лучшее из них. Вбивать в одну строку через пробелы (разделители) последовательность я думаю нельзя, но если бы можно было подскажите каким образом выдрать пропущенные (недостающие) элементы натурального ряда.
Вы немного не поняли. На входе будет таблица из множества строк, содержащих идентификаторы, с пропусками, а на выходе резалт сет из одной строки одной колонки, содержащий перечисление пропусков через запятую (или другой разделитель). Если такой способ подойдет, то я знаю специфичное решение на диалекте MySQL.

P. S. Вы правы qwerty112 . Если бы не такая тупость и одновременно сложность в постановке задачи, то еще можно было бы говорить о производительности. Но ... Теперь я сам же пропускаю ограничения на один select - запрос и какая СУБД не имеет значения и это не предел, но надеюсь уже достаточно.
qwerty112и плевать на сложность/время выполнения - главное, что такая возможность есть
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131484
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhYqwerty112я правда не знаю, что он имел ввиду под "соотнесённых под запросов"пропущено...

Имел ввиду такого вида: СООТНЕСЕННЫЕ ПОДЗАПРОСЫ .
Я бы вам советовал использовать термин коррелированный подзапрос (correlated subquery, dependent subquery). Соотнесенный подзапрос я встречаю впервые, несмотря на то, что это статья на SQL.ru.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131508
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 21.02.2011 23:16, ArhY wrote:

> Написать *один* select - запрос, который бы вывел все числа из каждого
> "пропуска" последовательности.
> *Например:*
> Последовательность: 1,2,3,7,8,9,11,20,....
> Решение: 4,5,6,10,12,13,14,15,16,17,18,19,...
>
> Каждое число последовательности это запись в столбике T.ID.
>
> То есть SELECT - запрос должен вывести те числа, которые нужно вставить в
> последовательность, чтобы получить ряд натуральных чисел. Как это сделать?

Это НУЖНО делать с помощью обычного цикла.
Делать это с помощью SQL нецелесообразно.
К тому же SQL не может генерировать новые данные из ниоткуда,
вам придётся как минимум создать таблицу всех номеров

1,2,3,4,5,....(бесконечность)


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131527
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhY,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
USE test;
CREATE TABLE test(
  id INT PRIMARY KEY
)
          SELECT   1  id
UNION ALL SELECT   2 
UNION ALL SELECT   5 
UNION ALL SELECT   6 
UNION ALL SELECT   9 
UNION ALL SELECT  10 ;

SELECT SUBSTR(@result,  3 ) result
FROM (
    SELECT BENCHMARK(t.id, (SELECT LEAST( 0 , @rownum := @rownum +  1 , CASE WHEN NOT EXISTS(SELECT null FROM test tii WHERE tii.id = @rownum) THEN @result := CONCAT_WS(', ', @result, @rownum) END)))
    FROM (SELECT @rownum :=  0 , @result := '') v, (SELECT MAX(ti.id) id FROM test ti) t
  ) tt;

DROP TABLE test;

Уверен, запрос можно оптимизировать. :) Впрочем, этот запрос достаточно извращен в любом случае.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131782
SQL Bigot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot ArhY]
1. Дана таблица T (какая СУБД не имеет значения).
2. В таблице есть 1 столбец с названием ID.
3. В таблице располагается натуральная, возрастающая последовательность с "пропусками".


для оракла, например, так:
Код: plaintext
1.
select num_val from table(generator_natural(select max(id) from T /*restiction to generator*/) )gnr
where not exists( select id from T tbl where tbl.id=gnr.num_val)


где generator_natural - твоя юзерская табличная функция, которая возвращает натуральную последовательность, ограниченную параметром, хотя в оракле можно и без функции достать последовательность нужную:
Код: plaintext
select level from dual connect by level <= (select max(id) from T)

вот проверенное решение (для оракла :):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select its_a_hole_id
  from (select level its_a_hole_id
          from dual
        connect by level <= (select max(tbl.natural_id_with_holes)
                               from your_table_with_holes tbl)) gnr
 where not exists
 (select natural_id_with_holes
          from your_table_with_holes tbl
         where tbl.natural_id_with_holes = gnr.its_a_hole_id)
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37131902
Богдан Гоцкий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверно наиболее быстрый способ:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
-- http://seqengine.org
-- README for build instructions
INSTALL PLUGIN SeqEngine SONAME 'ha_seqengine.so';

SHOW PLUGIN; SHOW ENGINES;

CREATE TABLE million (i TIMESTAMP NOT NULL)
ENGINE=SeqEngine CONNECTION=‘ 1 ; 1000000 ; 1 ‘;

-- If you want to… now it‘s materialized (fast!)
ALTER TABLE million ENGINE=MyISAM;
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37132867
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
an0nymя бы не стал трогать базовую таблицу - дешевле системную.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT t1.id
FROM t
  RIGHT JOIN (
    SELECT ti.id
    FROM (
        SELECT @rownum := @rownum +  1  id
        FROM (SELECT @rownum :=  0  rownum) v,
          (SELECT null UNION ALL SELECT null) tii1,
          (SELECT null UNION ALL SELECT null) tii2,
          ...
          (SELECT null UNION ALL SELECT null) tiiM
      ) ti
    WHERE ti.id <= N
  ) t1 ON t.id = t1.id
WHERE t.id IS NULL

Да. Так работает. У меня сервер MySQL под *nix системой, поэтому заменил маленькую t на большую T. Для примера который есть в самом первом посте M >= 5, N <= (SELECT MAX(T.id) FROM T) или просто <= 20.

Следующее решение лучше тем, что не используется декартово произведение, а просто пробегаем от 0 до MAX(T.ID) и смотрим с помощью EXIST есть ли @rownum в исходной таблице. Не понял зачем там USE, CREATE, DROP. Вроде и без них работать должно.
an0nym
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
USE test;
CREATE TABLE test(
  id INT PRIMARY KEY
)
          SELECT   1  id
UNION ALL SELECT   2 
UNION ALL SELECT   5 
UNION ALL SELECT   6 
UNION ALL SELECT   9 
UNION ALL SELECT  10 ;

SELECT SUBSTR(@result,  3 ) result
FROM (
    SELECT BENCHMARK(t.id, (SELECT LEAST( 0 , @rownum := @rownum +  1 , CASE WHEN NOT EXISTS(
        SELECT null FROM test tii WHERE tii.id = @rownum)
            THEN @result := CONCAT_WS(', ', @result, @rownum) END)))
    FROM (SELECT @rownum :=  0 , @result := '') v, (SELECT MAX(ti.id) id FROM test ti) t
  ) tt;

DROP TABLE test;
Уверен, запрос можно оптимизировать. :) Впрочем, этот запрос достаточно извращен в любом случае.


Вопрос. Вроде понимаю, как это должно работать, но когда проверяю аналогичный запрос на работоспособность, то выбивает предупреждение и всё. BENCHMARK(20, Бла-бла) работает нормально, а вот BENCHMARK(t.id, Бла-Бла) - не работает, хотя
Код: plaintext
SELECT MAX(ti.id) id FROM test ti) t
вбивает (для нашего примера) 20 в t.id. Пробовал и так и сяк. Что делать??? Справку по BENCHMARK смотрел тут: Information Functions . Это для MySQL 5.5, я использую MySQL 5.0, думаю проблема не в том. Проблема в том, что скаляр может быть параметром, а значение с таблицы с 1 колонкой и 1 записью почему-то нет (по крайней мере у меня не может).

Спасибо an0nym классный вариант для MySQL.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37132879
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SQL Bigot , для Oracle, впрочем как и для других серверов БД, интересны решения, которые не используют мои юзерские функции, а вот этот вариант действительно интересен.
SQL Bigotвот проверенное решение (для оракла :):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select its_a_hole_id
from (
    select level its_a_hole_id
    from dual
    connect by level <= (
        select max(tbl.natural_id_with_holes)
        from your_table_with_holes tbl
    )
) gnr
where not exists (
    select natural_id_with_holes
    from your_table_with_holes tbl
    where tbl.natural_id_with_holes = gnr.its_a_hole_id)

Попробую скачать Oracle и разобраться.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37132881
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArhY,

покажите конечный запрос и ошибку, которую он выдает.

Насчет 5.0 сейчас лень вспоминать, возможно там что-нибудь из того, что я использую не поддерживается. Если вы обучаетесь MySQL, с 5.0 начинать не советую - как минимум 5.1, а лучше 5.5.
...
Рейтинг: 0 / 0
Волшебство с помощью чистого SELECTA-а.
    #37134738
ArhY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
an0nymпокажите конечный запрос и ошибку, которую он выдает.

Насчет 5.0 сейчас лень вспоминать, возможно там что-нибудь из того, что я использую не поддерживается. Если вы обучаетесь MySQL, с 5.0 начинать не советую - как минимум 5.1, а лучше 5.5.
Мой запрос это результат выбрасывания под-запросов с приведённого Вами запроса, в попытках выяснить что не так. Вот приведённый Вами запрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT SUBSTR(@result,  3 ) result
FROM (
    SELECT BENCHMARK(t.id, (SELECT LEAST( 0 , @rownum := @rownum +  1 , CASE WHEN NOT EXISTS(
        SELECT null FROM T tii WHERE tii.id = @rownum)
            THEN @result := CONCAT_WS(', ', @result, @rownum) END)))
    FROM (SELECT @rownum :=  0 , @result := '') v, (SELECT MAX(ti.id) id FROM T ti) t
  ) tt;

Результат выполнения на MySQL 5.0 :
MySQL said:#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'T.id, (SELECT LEAST(0, @rownum := @rownum + 1, CASE WHEN NOT EXISTS(
SE' at line 3
Результат выполнения на MySQL 5.5 :
1 row in set (0.00 sec)+---------------------------------------------+
4, 5, 6, 10, 12, 13, 14, 15, 16, 17, 18, 19
+---------------------------------------------+
Что является правильным результатом. Повторюсь: всё из-за того, что в MySQL 5.0 BENCHMARK не хочет в качестве количества повторений принимать t.id, а только конкретное число (скаляр). Но указание конкретного числа, это явно хуже чем использование
Код: plaintext
(SELECT MAX(ti.id) id FROM T ti) t
Собственно всё ясно. Конечно же я не читал "New Features" к каждой версии MySQL 5.x, поэтому не смог сразу определить, что причина в BENCHMARK. А может быть причина конкретно в том дистрибутиве MySQL 5.0, на котором я тестировал, каждое предложенное решение. Но это не так важно. Главное, что работает.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Волшебство с помощью чистого SELECTA-а.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]