На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
  
> Нетривиальная сортировка , [PostgreSQL][MySQL][Sqlite3]
    Есть таблица, пусть для "синтетического" примера - просто таблица целых чисел. Числа могут повторяться и не могут принимать значение NULL. Нужно вывести сортированный список по возрастанию "дистанции".

    Определение "дистанции

    Dij = ABS(ABS(Ti)-ABS(Tj))

    Где:

    • Dij - дистанция между i-м и j-м элементом
    • Ti,Tj - i-й и j-й элементы таблицы

    Правила сортировки

    • Dij<Djk
    • Если на очередной итерации сортировки на место очередной пары претендуют несколько пар (Dij==Djk), выбирается та пара, у которой есть число - наименьшее из всех чисел из данных пар
    • по возможности Ti < Tj

    Поправка

    "Возрастание дистанции" - скорее всего не совсем верная формулировка. Потому как выбор очередной пары зависит от предыдущей. Иными словами - второй элемент предыдущей пары на очередной итерации становится первым в текущей. Поэтому "дистанции" могут "плясать". Типа 2-3-10-1-2-2-7-3...

    Для теста

    ExpandedWrap disabled
          CREATE TABLE Test (
            Digit INT NOT NULL
          );
       
          INSERT INTO Test (Digit)
          VALUES (17),(16),(9),(8),(7),(3),(0),(-5),(-10),(-17);


    Нужный порядок сортировки:

    ExpandedWrap disabled
          -17
          17
          16
          -10
          9
          8
          7
          -5
          3
          0


    Добавлено
    Еще для теста:
    ExpandedWrap disabled
      -1,-1,4,-5
      Тоже мне проблема. Это же тупое
      ExpandedWrap disabled
        ORDER BY ABS(Digit) /* DESC */

      А по возрастанию или убыванию - формально определяется тем, с какой из сторон разность мельче.
      Сообщение отредактировано: Akina -
        Цитата Akina @
        Тоже мне проблема. Это же тупое

        ExpandedWrap disabled
          -1,-1,0,-4,5
          А мне вариант 0,-1,-1,-4,5 больше нравится...
            Цитата Akina @
            А мне вариант 0,-1,-1,-4,5 больше нравится...

            Не подходит под условие.
            Ибо ABS(ABS(0)-ABS(-1)) > ABS(ABS(-1)-ABS(-1))
            А это чудовищный косяк! :wall: Шютка) ... В слове "чудовищный" :lol:
              Цитата JoeUser @
              Не подходит под условие.
              Ибо ABS(ABS(0)-ABS(-1)) > ABS(ABS(-1)-ABS(-1))

              А то, что дальше это условие не ыполняется, тебе походу пофиг...
                На стековерфлове ответили, но еще не разбирался, положил в "zakroma of rodina":

                ExpandedWrap disabled
                  WITH RECURSIVE Q(Digit,ids,Level) as (
                    select * from (
                      select a.Digit,','||a.rowid ids,0 as Level
                      from Test a, Test b
                      where a.rowid!=b.rowid
                      order by abs(abs(a.Digit)-abs(b.Digit)),a.Digit
                      limit 1
                    ) A
                    union all
                    select a.Digit,ids||','||a.rowid,Level+1
                    from Q, Test a
                    where a.rowid in(
                      select b.rowid from Test b,(select Q.digit as d) C
                      where Q.ids||',' not like '%,'||b.rowid||',%'
                      order by abs(abs(b.Digit)-abs(C.d)),b.Digit
                      limit 1
                    )
                  )
                  select Digit from Q order by Level


                Добавлено
                Цитата Akina @
                А то, что дальше это условие не ыполняется, тебе походу пофиг...

                Как не выполняется?

                1) Минимальная дистанция для всего набора -1 и -1 = 0, гуд (очередной последний элемент = "-1")
                2) Вторая пара -1 и 0, дистанция 1, меньше нет, гуд (очередной последний элемент = "0")
                3) Третья пара 0 и -4, дистанция 4, гуд (очередной последний элемент = "-4")
                4) Последняя пара -4 и 5, дистанция 1 - готово. (очередных элементов нед)

                Что не так?
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0288 ]   [ 15 queries used ]   [ Generated: 29.03.24, 06:15 GMT ]