2009-04-15 9 views
0

J'ai une table avec colonne varchar (128) avec des données comme:Comment inverser les mots dans une colonne

mot1, mot2,, mot3, word4
mot1, mot2, mot3,,
word1 ,, ,,; mot2
; mot1 mot2, MOT3

Je dois mettre à jour ce tableau, faire des mots l'ordre inverse:

word4,, mot3,, mot2, word1
,, mot3,, mot2, word1

Pourriez-vous m'aider à le faire en utilisant seulement une seule requête SQL?

+0

Est-ce que les virgules et les points-virgules importance? – Quassnoi

+0

Cette question pourrait être clarifiée. – Jeremiah

+0

Qu'est-ce qui sépare les mots? espace? virgule? point-virgule? – fredrik

Répondre

1

La meilleure chose à faire serait de ne jamais stocker de données de cette façon. Si c'était dans une table liée comme il se doit, alors vous pourriez commander le contenu de votre coeur. Personnellement, il serait probablement plus rapide de diviser au moins les données en une variable table ou table tentable qui a une colonne d'identité supplémentaire, puis de trier dans l'ordre desc sur cette colonne.

0

Je pense que vous pourriez créer une nouvelle table et insérer dans cette table les données de la première table.

INSERT INTO TABLEAU2 SELECT * DÉCRET TABLE1 PAR COLUMN1 DESC

Ensuite, laissez tomber table2 et renomme table1.

... Peut-être

0

merci pour vos réponses

mots sont séparés par des espaces, des virgules et/ou des points-virgules, tous les séparateurs doivent rester en place

par exemple enregistrement

'mot1, mot2 ;;; mot3,'

evalueates à

'mot3, word2 ;;; word1,'

en raison des exigences du système existant de se faire, il doit en utilisant seule requête,

j'ai essayé:

update t_desc set name = 
(select name 
from 
(select name, 
case when wb is null then rname when wb >= we then stuff(rname, wb, 128, REVERSE  (substring(rname, wb, 128))) else 
stuff(rname, wb, we-wb+1, REVERSE(substring(rname, wb, we-wb+1))) end rname, 
case when wb is null or wb > we then null else PATINDEX('%[a-z0-9]%', SUBSTRING(rname, we+1, 128))+we end wb, 
case when we is null or wb > we then null else PATINDEX('%[a-z0-9][^a-z0-9]%', SUBSTRING(rname, we+1, 128))+we end we 
from 
(select name, 
case when wb is null then rname when wb >= we then stuff(rname, wb, 128, REVERSE (substring(rname, wb, 128))) else 
stuff(rname, wb, we-wb+1, REVERSE(substring(rname, wb, we-wb+1))) end rname, 
case when wb is null or wb > we then null else PATINDEX('%[a-z0-9]%', SUBSTRING (rname, we+1, 128))+we end wb, 
case when we is null or wb > we then null else PATINDEX('%[a-z0-9][^a-z0-9]%',  SUBSTRING(rname, we+1, 128))+we end we 
from 
(select name, 
case when wb is null then rname when wb >= we then stuff(rname, wb, 128, REVERSE  (substring(rname, wb, 128))) else 
stuff(rname, wb, we-wb+1, REVERSE(substring(rname, wb, we-wb+1))) end rname, 
case when wb is null or wb > we then null else PATINDEX('%[a-z0-9]%', SUBSTRING  (rname, we+1, 128))+we end wb, 
case when we is null or wb > we then null else PATINDEX('%[a-z0-9][^a-z0-9]%',   SUBSTRING(rname, we+1, 128))+we end we 
from 
(select name, 
stuff(rname, wb, we-wb+1, REVERSE(substring(rname, wb, we-wb+1))) rname, 
PATINDEX('%[a-z0-9]%', SUBSTRING(rname, we+1, 128))+we wb, 
PATINDEX('%[a-z0-9][^a-z0-9]%', SUBSTRING(rname, we+1, 128))+we we 
from 
(select name, rname, 
PATINDEX('%[a-z0-9]%', rname) wb, 
PATINDEX('%[a-z0-9][^a-z0-9]%', rname) we 
    from 
(select t_desc.name, REVERSE(name) rname) t1) t2) t3) t4) t5) t6) 

et des idées similaires, mais il a été fonctionne pas correctement

modifier: tout sauf les lettres et les chiffres sont des séparateurs

Edit2: Unfortunetely i ne peut invoquer les instructions ddl et je n'ont pas accès direct à la base de données, Mon entreprise utilise un ancien logiciel fermé - nous pouvons uniquement utiliser la console de l'application externe pour sélectionner ou parfois mettre à jour. Je peux ajouter ma mise à jour à la liste d'emplois - elle sera effectuée tous les jours à l'avenir.

Table

a environ 60k lignes, colonne contient entre 2 et environ 20 mots, non null

désolé pour mon anglais :)

0

J'ai une pensée puisque vous êtes limité à une requête. Pouvez-vous créer un fichier UDF de valeur table qui ferait la même chose que la table temporaire que j'ai suggérée plus tôt? Joignez-vous à cela et commandez desc. Il ne sera pas performant (bien sûr, rien ne sera fait lorsque la structure est aussi mal conçue), mais il pourrait faire l'affaire à moins que vous n'ayez des millions d'enregistrements.

Ou pouvez-vous faire un proc stocké et simplement appeler cela à partir de votre GUI, qui vous permettra d'avoir plusieurs étapes.

2

Pour accomplir cette tâche, vous aurez besoin d'une fonction t-sql et d'un curseur. fn_SplitList vous permettra de diviser en fonction d'un délimiteur. Une fois que vous avez cette fonction, vous pouvez créer un curseur pour exécuter vos données en mettant à jour chaque enregistrement. J'ai créé un exemple en utilisant @ table1.

Fonction

CREATE FUNCTION [dbo].[fn_SplitList] 
(
    @RowData varchar(8000), 
    @SplitOn varchar(5) 
) 
RETURNS @RtnValue table 
(
    Id int identity(1,1), 
    Data varchar(100) 
) 
AS 
BEGIN 
    Declare @Cnt int 
    Set @Cnt = 1 

    While (Charindex(@SplitOn,@RowData)>0) 
    Begin 
     Insert Into @RtnValue (data) 
     Select 
      Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1))) 

     Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData)) 
     Set @Cnt = @Cnt + 1 
    End 

    Insert Into @RtnValue (data) 
    Select Data = ltrim(rtrim(@RowData)) 

    Return 
END 

code pour effectuer de mise à jour

declare @table1 table(id int primary key 
        ,words varchar(max)) 
declare @id int 
declare @words varchar(max) 

insert into @table1 values(0, 'word1, word2, , word3, word4') 
insert into @table1 values(1, 'word1, word2, word3, ,') 
insert into @table1 values(2, 'word1,,,, ; word2') 
insert into @table1 values(3, ';word1 word2, word3') 

declare updateCursor cursor for 
select id 
     ,words 
    from @table1 

open updateCursor 
fetch next from updateCursor into @id, @words 
while @@fetch_status = 0 
begin 
    declare @row varchar(255) 

    select @row = coalesce(@row+', ', '') + data 
    from dbo.fn_SplitList(@words, ',') 
    order by id desc 

    update @table1 
    set words = @row 
    where id = @id 

    fetch next from updateCursor into @id, @words 
end 
close updateCursor 
deallocate updateCursor 

select * 
    from @table1 
Questions connexes