我有一个名为favorite_question的列,它被更新如下:
if it is null
then insert a value
if not null then old value + , + new value
if((select Favorite_question from User_Details where User_Id = @userid) IS NULL)
begin
update User_Details
set Favorite_question = (cast(@questionid as varchar(50)))
where User_Id = @userid
end
else
begin
update User_Details
set Favorite_question = ((select Favorite_question
from User_Details
where User_Id = @userid ) + ',' +
(cast(@questionid as varchar(50))))
where User_Id = @userid
end其中,@userid是用户价值,@questionid是问题价值
varchar(50)取favorite_question
我想从该列中随机删除一个值
例如。
如果列值为=2、6、8、9、5,并且我想从其中删除8或从上面删除任何值
同样的sql查询是什么?
发布于 2012-03-03 22:01:43
UPDATE语句可以优化很多。整个"if((select ...“可以替换为:
UPDATE User_Details
SET Favorite_question = COALESCE(Favorite_question + ',', '') +
cast(@questionid as varchar(50))
where User_Id = @userid现在来看您真正的问题:如何从Favorite_questions列中删除文本(数字)。假设该列包含值'2,6,8,9,5‘。如果你想删除2,你得到的是',6,8,9,5',所以必须添加处理逻辑来删除开头的孤立逗号。如果你想删除5,你得到的是'2,6,8,9,',所以必须添加处理逻辑来删除末尾的孤立逗号。如果你想删除8,你得到的是'2,6,,9,5',所以你必须添加处理逻辑来删除中间的一个双逗号。如果列包含值'12,6,8,29,5,2‘,而您想要删除'2',那么您不希望以'1,6,8,9,5’结束。
基本上,我们应该花费大量的精力来从文本中删除正确的数字,并使文本处于干净的状态(no ',6,8 ,9,5‘,'2,6,9,5’或诸如此类)。SQL在文本处理方面不是很好。
最基本的问题是你的数据模型没有标准化。您应该从User_Details表中删除列Favorite_question,并创建一个额外的表User_FavoriteQuestions (User_Id,Question_id)来为您的用户存储FavoriteQuestions。然后,您的第一个UPDATE语句将替换为
INSERT INTO User_FavoriteQuestions (User_Id, Question_id)
VALUES(@userid, @questionid)你真正的问题变成了:
DELETE FROM User_FavoriteQuestions
WHERE User_Id = @userid AND Question_id = @questionid一旦你规范化了你的数据模型,用SQL操作它就变得容易多了。
发布于 2012-03-03 22:22:47
好吧,这种级别的字符串操作并不是SQL的强项。然而,这是有可能的。
首先,如果您要对多个字符串执行此操作(或者即使是这种情况),您可能希望将其放入一个函数中。
为了更简单,一种方法是有一个只包含连续数字列表的数字表。这可以作为一个永久表,但在本例中,我将其显示为临时表。
declare @numberList table
(
NumberID int
)可以用一种单调乏味的方式填充它,但这是http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/the-ten-most-asked-sql-server-questions--1#3的一个巧妙技巧
insert into @numberList
select number from master..spt_values
where type = 'P'接下来,您需要将原始文本分成各个部分:
declare @question varchar(20)
declare @questionTable table
(
qNo int identity(1,1),
qChar varchar(10)
)
set @question = '2,6,8,9,5'
set @question = ',' + @question + ','
insert into @questionTable(qChar)
select SUBSTRING(@question,NumberID + 1,CHARINDEX(',', @question, NumberID + 1) - NumberID - 1)
from @numberList
where NumberID <= LEN(@question)-1
and SUBSTRING(@question, NumberID, 1) = ','然后,您需要确定要删除的随机部分
declare @numberCount int
declare @seed int
declare @posn int
select @numberCount = count(*) from @questionTable
set @seed = (DATEPART(mm, getdate())) * 100000 +( DATEPART(ss, getdate()) * 1000) + datepart(ms, getdate())
set @posn = (RAND(@seed) * @numberCount) + 1然后从临时表中删除该零件:
delete from @questionTable where qNo = @posn然后取回剩下的部分:
declare @output varchar(20)
select @output = coalesce(@output+',', '') + qChar
from @questionTable你不需要通过临时表就可以做到这一点,但是有很多CHARINDEX和替换...
发布于 2012-03-04 00:07:45
有几个步骤需要拉动的字符串操作。
declare @S varchar(20)
declare @R varchar(20)
-- String of values
set @S = '2,6,8,9,5'
-- Value to remove
set @R = '8'
-- Add extra commas before and after
set @S = ','+@S+','
set @R = ','+@R+','
-- Remove the value
set @S = stuff(@S, charindex(@R, @S), len(@R)-1, '')
-- Remove extra commas
set @S = substring(@S, 2, len(@S)-2)
select @S结果:
2,6,9,5如果您需要使用和更新来执行此操作,您可以使用cross apply来处理步骤:
declare @T table
(
S varchar(20)
)
insert into @T values('2,6,8,9,5')
declare @R varchar(20)
set @R = '8'
update T1
set S = substring(T3.S, 2, len(T3.S)-2)
from @T as T1
cross apply (select ','+T1.S+',') as T2(S)
cross apply (select stuff(T2.S, charindex(','+@R+',', T2.S), len(@R)+1, '')) as T3(S)
select *
from @T https://stackoverflow.com/questions/9546434
复制相似问题