SQL: переименуйте дублирующиеся имена файлов, добавив 1,2,3 ... перед расширением - PullRequest
1 голос
/ 06 ноября 2011

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

ID       | FILENAME
----------------------
1        | file1.ext
2        | file2.ext
3        | file1.ext
4        | file1.ext
5        | file3.ext
6        | file3.ext
7        | file4.ext

Итак, в приведенном выше примере я хочу, чтобы следующее было уникальным:

ID       | FILENAME
----------------------
1        | file1.ext
3        | file1.ext
4        | file1.ext
5        | file3.ext
6        | file3.ext

Изменяя имена файлов на:

ID       | FILENAME
----------------------
1        | file1-1.ext
3        | file1-2.ext
4        | file1-3.ext
5        | file3-1.ext
6        | file3-2.ext

Я знаю, как найти дубликаты, но я не уверен, как добавить приращения непосредственно перед расширением или как увеличить счетчик во-первых.

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 06 ноября 2011

Используйте оконную функцию row_number() для получения номера и replace для манипуляции со строками .
Вы не раскрыли свою СУБД.Следующий запрос протестирован на PostgreSQL 9.0.MySQL не поддерживает оконные функции, большинство других больших СУБД поддерживают.

Переименование все имена файлов :

SELECT id
      ,replace(filename, '.',  
               '-'
               || row_number() OVER (PARTITION BY filename ORDER BY id)
               || '.')
FROM   mytbl

Только переименование дубликаты имен файлов :

SELECT id
      ,CASE WHEN (count(*) OVER (PARTITION BY filename)) > 1 THEN
          replace(filename, '.',  
                  '-'
                  || row_number() OVER (PARTITION BY filename ORDER BY id)
                  || '.')
       ELSE filename END AS filename
FROM   mytbl;

Редактировать с помощью дополнительно запрашиваемых функций

Эта версия работает с несколькими точками в имени или без них.Протестировано в PostgreSQL 9.0.

SELECT id
      ,CASE WHEN (count(*) OVER (PARTITION BY filename)) > 1 THEN
          regexp_replace(filename
              -- pick the longest string from the start not 
             ,'^([^.]*)'containing a '.'
              -- and replace it with itself + row_number
             ,E'\\1-' || row_number() OVER (PARTITION BY filename ORDER BY id))
       ELSE filename END AS filename
FROM   mytbl
...