使用函数或spx从表中删除值

时间:2016-09-02 15:55:42

标签: sql sql-server sql-server-2008

我有一个表,该表将用户的值存储为:

ID     USERID      Items        
1       54           1,2,3,4,5,6
2       55           1,2,5,6,7,8
3       56           1,2,3,4,5,6
4       57           1,2,3,4,5,6
5       58           1,2,3,4,5,6
6       59           1,2,3,4,5,6
7       54           1,2,3,4,5,6

因此,我尝试从每个1,2,7

的项目列中删除值userId

我可以编写一个代码inphp,它可以运行并循环并在列列表中找到一个项目并删除但是这是预期的,最好将其作为sql进行操作

我可以做sql的基本功能但是我的高级知识并不多,我怎样才能删除这些项目

将我作为一个函数,我可以使用@declare = 'items as comma seperated to be removed'并编写某种循环,如果找到它将删除它

确实,我忘了提及,还有另一个名为users的表,其中包含基于Userid, firstname,lastName的用户详细信息,因此显然它将遍历用户表并且将循环遍历这是为了纠正

3 个答案:

答案 0 :(得分:2)

如果你想要一个更强大的解决方案(不仅是1,2和7,而是任何希望的序列)使用这个解决方案:

首先,创建一个split函数。只需复制/粘贴此信息(信用到此answer)代码:

CREATE FUNCTION Split (@InputString varchar(8000),
@Delimiter varchar(50))

RETURNS @Items TABLE (
  Item varchar(8000)
)

AS
BEGIN
  IF @Delimiter = ' '
  BEGIN
    SET @Delimiter = ','
    SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
  END

  IF (@Delimiter IS NULL
    OR @Delimiter = '')
    SET @Delimiter = ','

  DECLARE @Item varchar(8000)
  DECLARE @ItemList varchar(8000)
  DECLARE @DelimIndex int

  SET @ItemList = @InputString
  SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
  WHILE (@DelimIndex != 0)
  BEGIN
    SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
    INSERT INTO @Items
      VALUES (@Item)

    -- Set @ItemList = @ItemList minus one less item
    SET @ItemList = SUBSTRING(@ItemList, @DelimIndex + 1, LEN(@ItemList) - @DelimIndex)
    SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
  END -- End WHILE

  IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
  BEGIN
    SET @Item = @ItemList
    INSERT INTO @Items
      VALUES (@Item)
  END

  -- No delimiters were encountered in @InputString, so just return @InputString
  ELSE
    INSERT INTO @Items
      VALUES (@InputString)

  RETURN

END -- End Function
GO

编辑:根据@Sean Lange评论,请考虑更好的性能拆分功能,如here所述。

其次,这是代码:

DECLARE @table TABLE (
  ID int,
  UserID int,
  Items varchar(50)
);

INSERT INTO @table (ID, UserID, Items)
  VALUES (1, 54, '1,2,3,4,5,6'), (2, 55, '1,2,5,6,7,8'), (3, 56, '1,2,3,4,5,6'),
  (4, 57, '1,2,3,4,5,6'), (5, 58, '1,2,3,4,5,6'), (6, 59, '1,2,3,4,5,6'), (7, 54, '1,2,3,4,5,6');

DECLARE @toBeRemoved TABLE (
  num varchar(16)
);
INSERT INTO @toBeRemoved (num)
  VALUES ('1'), ('2'), ('7');

DECLARE @forUserIds TABLE (
  userId int
);
INSERT INTO @forUserIds (userId)
  VALUES (54), (55), (56), (57), (58);

SELECT
  ID,
  UserID,
  Items,
  LEFT([Sub].[NewItems], LEN([Sub].[NewItems]) - 1) AS 'NewItems'
FROM (SELECT DISTINCT
  ST2.*,
  (SELECT
    ST1.Item + ',' AS [text()]
  FROM (SELECT
    *
  FROM @table a
  CROSS APPLY dbo.Split(Items, ',')
  WHERE Item NOT IN (SELECT
    num
  FROM @toBeRemoved)) ST1
  WHERE ST1.ID = ST2.ID
  ORDER BY ST1.ID
  FOR xml PATH (''))
  [NewItems],
  ROW_NUMBER() OVER (PARTITION BY ID ORDER BY id) AS RowNo
FROM (SELECT
  *
FROM @table a
CROSS APPLY dbo.Split(Items, ',')
WHERE Item NOT IN (SELECT
  num
FROM @toBeRemoved)) ST2) [Sub]
WHERE RowNo = 1
AND UserID IN (SELECT
  userId
FROM @forUserIds);

注意@toBeRemoved表和@forUserIds表。这些正是您可以根据需要更改的表并动态修改。结果取决于这些表。 @table仅用于测试目的。用你的实际表格替换它。

Edit2:这是sql update语句,而不是select。我将@table更改为YourTable。只需使用您的表名。

UPDATE YourTable
SET Items = LEFT([Sub].[NewItems], LEN([Sub].[NewItems]) - 1)
FROM (SELECT DISTINCT
  ST2.*,
  (SELECT
    ST1.Item + ',' AS [text()]
  FROM (SELECT
    *
  FROM YourTable a
  CROSS APPLY dbo.Split(Items, ',')
  WHERE Item NOT IN (SELECT
    num
  FROM @toBeRemoved)) ST1
  WHERE ST1.ID = ST2.ID
  ORDER BY ST1.ID
  FOR xml PATH (''))
  [NewItems],
  ROW_NUMBER() OVER (PARTITION BY ID ORDER BY id) AS RowNo
FROM (SELECT
  *
FROM YourTable a
CROSS APPLY dbo.Split(Items, ',')
WHERE Item NOT IN (SELECT
  num
FROM @toBeRemoved)) ST2) [Sub]
WHERE [Sub].RowNo = 1
AND [Sub].UserID IN (SELECT
  userId
FROM @forUserIds)
AND [Sub].ID = YourTable.ID;

SELECT
  *
FROM YourTable

答案 1 :(得分:1)

您可以这样做:

update t
    set items = stuff(stuff(new_items, len(new_items) - 1, 1, ''), 1, 1, '') 
    from (select t.*,
                 replace(replace(replace(',1,', ',' + items + ',', ''
                                        ), ',2,', ''
                                ), ',7,', ''
                        ) as new_items
          from t
         ) t;

new_items是删除了1,2和7的项目列表,但仍以逗号开头和结尾。 stuff()函数用于删除前导和尾随逗号。

答案 2 :(得分:0)

这样的事情会起作用......

declare @CommaSeparatedValues varchar = '1,'
update TableName
set Items = REPLACE(Items, @CommaSeparatedValues, '')