Как я могу изменить порядок строк в базе данных SQL - PullRequest
35 голосов
/ 01 мая 2009

Можно ли изменить порядок строк в базе данных SQL? Например; как поменять местами порядок значений 2-го ряда и 3-го ряда?

Порядок строки важен для меня, так как мне нужно отобразить значение в соответствии с порядком.


Спасибо за все ответы. Но «Заказ по» не будет работать для меня.

Например, я положил список закладок в базу данных. Я хочу отобразить на основе результата, который я получаю из запроса. (не в алфавитном порядке). Просто когда они вставлены.

Но пользователь может изменить расположение закладки (любым способом, который он / она хочет). Поэтому я не могу использовать «заказ по».

Например, как закладка отображается в закладке в Firefox. Пользователь может легко менять положение. Как я могу упомянуть это в БД?

Спасибо.

Ответы [ 12 ]

67 голосов
/ 01 мая 2009

Похоже, вам нужен еще один столбец, как "ListOrder". Таким образом, ваш стол может выглядеть так:

BookMark ListOrder
======== =========
  d        1
  g        2
  b        3
  f        4
  a        5

Тогда вы можете «заказать» ListOrder.

Select * from MyTable Order By ListOrder

Если пользователь может перемещать закладки только по одному месту за раз, вы можете использовать целые числа как ListOrder и поменять их местами. Например, если пользователь хочет переместить «f» на одну строку вверх:

Update MyTable
    Set ListOrder=ListOrder+1
        Where ListOrder=(Select ListOrder-1 From MyTable where BookMark='f')

Update MyTable
    Set ListOrder=ListOrder-1
        Where BookMark='f'

Если пользователь может переместить закладку вверх или вниз на несколько строк одновременно, вам необходимо изменить порядок сегментов. Например, если пользователь хочет переместить «f» в начало списка, вам необходимо:

update MyTable
    Set ListOrder=ListOrder+1
        where ListOrder>=1 -- The New position
            and ListOrder <(Select ListOrder from MyTable where BookMark='f')

 update MyTable
     Set ListOrder=1 -- The New Position
         Where Bookmark='f'
18 голосов
/ 01 мая 2009

Как уже упоминали другие, не стоит полагаться на физический порядок таблицы базы данных. Реляционные таблицы концептуально больше похожи на неупорядоченные множества, чем упорядоченные списки. Предположение, что определенный физический порядок может привести к непредсказуемым результатам.

Похоже, вам нужен отдельный столбец, в котором хранится предпочтительный порядок сортировки пользователя. Но вам все равно нужно будет что-то сделать в своем запросе, чтобы отобразить результаты в указанном порядке.

Можно указать физический порядок записей в базе данных, создав кластеризованный индекс, но это не то, что вы хотели бы делать произвольно по заданному пользователем принципу. И это все еще может привести к неожиданным результатам.

9 голосов
/ 01 мая 2009

Используйте ORDER BY в запросе SELECT. Например, чтобы заказать по фамилии пользователя, используйте:

SELECT * FROM User ORDER BY LastName
4 голосов
/ 01 мая 2009

Порядок строк в фактической базе данных не должен иметь значения.

Вы должны использовать в своих запросах предложение ORDER BY, чтобы упорядочить их по мере необходимости.

3 голосов
/ 01 мая 2009

Базы данных могут хранить данные любым удобным для них способом. Использование условия "order by" - это only способ гарантировать порядок данных. В вашем примере закладки вы могли бы иметь целочисленное поле, которое указывает порядок, а затем обновлять это поле, когда пользователь перемещает объекты. Затем закажите в этом столбце все в правильном порядке.

1 голос
/ 08 ноября 2010

У меня есть решение для этого, которое я использовал несколько раз. Я сохраняю дополнительное поле «sort_order» в таблице и обновляю его при переупорядочении. Я использовал это в тех случаях, когда у меня есть какие-то контейнеры с элементами, и порядок элементов должен быть редактируемым внутри контейнера. При переупорядочении я обновляю sort_order только для элементов в текущем контейнере, что означает, что не нужно обновлять много (обычно на практике только несколько) строк.

Короче, я делаю следующее:

  1. добавить поле sort_order в таблицу элементов
  2. при вставке новой строки я устанавливаю sort_order = id
  3. при переупорядочении (нужен идентификатор элемента для перемещения и идентификатор элемента для вставки после):
    • выберите id, sort_order из элементов, в которых контейнер = порядок ID по sort_order
    • разделить id и sort_order из строк в двух массивах
    • удалить идентификатор элемента для перемещения из списка идентификаторов
    • вставить идентификатор элемента для перемещения после идентификатора элемента для вставки после
    • объединить список идентификаторов и список sort_order в двумерный массив, как [[id, sort_order], [id2, sort_order], ...]
    • run update item set sort_order=SORT_ORDER where id=ID (executemany) с объединенным списком

(При перемещении элемента в другой контейнер после обновления «внешний ключ контейнера» перемещайтесь первым или последним в зависимости от приложения.)

(Если обновление включает в себя большое количество элементов, я не думаю, что это решение является хорошим подходом.)

Я сделал пример использования python и mysql на http://wannapy.blogspot.com/2010/11/reorder-rows-in-sql-database.html (скопируйте и попробуйте) вместе с некоторыми дополнительными пояснениями.

1 голос
/ 01 мая 2009

Как заявили другие, используйте заказ по.
Никогда не зависите от порядка данных в физической таблице, всегда основывайте его на данных, с которыми вы работаете, будь то одно или несколько ключевых полей.

1 голос
/ 01 мая 2009

Я думаю, простое order by будет тем, что вы ищете?

select my_column from my_table order by my_order_column;
0 голосов
/ 18 мая 2009

Добавьте столбец position в таблицу и сохраните его в виде простого целого числа.

Если вам требуется поддержка нескольких пользователей или списков, лучше всего создать таблицу закладок, таблицу пользователей и таблицу для их связи.

  • закладки: id,url
  • пользователи: id,name
  • users_bookmarks: user_id, bookmark_id, position, date_created

Предполагая, что date_created заполняется при вставке строк, вы можете получить вторичное упорядочение списка по дате.

select bookmark_id from users_bookmarks where user_id = 1 order by position, date_created;
0 голосов
/ 02 мая 2009

В вопросе отсутствуют какие-либо подробности, которые позволили бы кому-либо дать вам правильный ответ. Очевидно, что вы можете прочитать записи в память, а затем обновить их. Но это плохо на многих разных уровнях.

Проблема такая. В зависимости от реально реализованной схемы существует логика в том, как записи физически записываются на диск. Иногда они пишутся в порядке вставки, а иногда они вставляются с пробелом между блоками (см. Экстенты).

Таким образом, изменение физического порядка маловероятно без обмена данными столбца; и это оказывает глубокое влияние на различные показатели. Вам остается изменить логический порядок.

Когда я читаю ваше обновление ... Мне остается понять, что у вас может быть несколько пользователей, и у каждого пользователя должны быть закладки, которые они хотят заказать. Похоже, вам нужна вторая таблица, которая действует как пересечение между пользователем и закладкой. Тогда все, что вам нужно, это внутреннее соединение и заказ.

Но недостаточно информации, чтобы предложить полное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...