【问题标题】:How do I delete multiple rows with different IDs?如何删除具有不同 ID 的多行?
【发布时间】:2011-05-01 18:39:36
【问题描述】:

我想做这样的事情:

DELETE FROM table WHERE id IN (SELECT ....)

我该怎么做?

【问题讨论】:

  • 什么数据库?在大多数情况下,你所描述的应该是可行的。
  • 你怎么不能这样做?什么不工作?你用什么数据库? Oracle/MySql/SqlServer?
  • 澄清你从哪里得到 ID 列表...,是的,可以删除 where id in ...
  • 你的代码有什么问题?它应该可以工作。
  • DELETE FROM table WHERE id IN (1,2,3,4)DELETE FROM table WHERE id IN (SELECT id FROM table2 WHERE X=Y) 你真正想知道什么?

标签: sql sql-delete


【解决方案1】:
  • 你可以做这个。

    创建过程 [dbo].[sp_DELETE_MULTI_ROW]
    @CODE XML ,@ERRFLAG CHAR(1) = '0' 输出

作为

设置编号
设置事务隔离级别读取未提交

删除 tb_SampleTest 在哪里 代码输入( SELECT Item.value('.', 'VARCHAR(20)') FROM @CODE.nodes('RecordList/ID') AS x(Item) )

如果@@ROWCOUNT = 0 设置@ERRFLAG = 200

设置 NOCOUNT 关闭

  • 12'/ID'>

【讨论】:

    【解决方案2】:
    Delete from BA_CITY_MASTER where CITY_NAME in (select CITY_NAME from BA_CITY_MASTER group by CITY_NAME having count(CITY_NAME)>1);
    

    【讨论】:

    • 您应该通过选择代码并按 ctrl-k 来格式化您的代码。此外,它有助于提供一些解释,也许会暗示问题中的代码有什么问题(如果有的话)。
    • 这是一个很好的解决方案:DELETE FROM [TableName] WHERE [ColumnName] IN (SELECT [ColumnName] FROM [TableName] GROUP BY [ColumnName] HAVING COUNT([ColumnName])>1);
    【解决方案3】:

    Disclaim: the following suggestion could be an overhead depending on the situation. The function is only tested with MSSQL 2008 R2 but seams be compatible to other versions

    如果您想对许多 ID 执行此操作,您可以使用 function 创建一个临时表,您可以在其中从选择中删除

    查询的样子:

    -- not tested
    -- @ids will contain a varchar with your ids e.g.'9 12 27 37'
    DELETE FROM table WHERE id IN (SELECT i.number FROM iter_intlist_to_tbl(@ids))
    

    函数如下:

    ALTER FUNCTION iter_intlist_to_tbl (@list nvarchar(MAX))
       RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
                           number  int NOT NULL) AS
    
       -- funktion gefunden auf http://www.sommarskog.se/arrays-in-sql-2005.html
       -- dient zum übergeben einer liste von elementen
    
    BEGIN
        -- Deklaration der Variablen
        DECLARE @startpos int,
                @endpos   int,
                @textpos  int,
                @chunklen smallint,
                @str      nvarchar(4000),
                @tmpstr   nvarchar(4000),
                @leftover nvarchar(4000)
    
        -- Startwerte festlegen
       SET @textpos = 1
       SET @leftover = ''
    
       -- Loop 1
        WHILE @textpos <= datalength(@list) / 2
        BEGIN
    
            --
            SET @chunklen = 4000 - datalength(@leftover) / 2 --datalength() gibt die anzahl der bytes zurück (mit Leerzeichen)
    
            --
            SET @tmpstr = ltrim(@leftover + substring(@list, @textpos, @chunklen))--SUBSTRING ( @string ,start , length ) | ltrim(@string) abschneiden aller Leerzeichen am Begin des Strings
    
            --hochzählen der TestPosition
            SET @textpos = @textpos + @chunklen
    
            --start position 0 setzen
            SET @startpos = 0
    
            -- end position bekommt den charindex wo ein [LEERZEICHEN] gefunden wird
            SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr)--charindex(searchChar,Wo,Startposition)
    
            -- Loop 2
            WHILE @endpos > 0
            BEGIN
                --str ist der string welcher zwischen den [LEERZEICHEN] steht
                SET @str = substring(@tmpstr, @startpos + 1, @endpos - @startpos - 1) 
    
                --wenn @str nicht leer ist wird er zu int Convertiert und @tbl unter der Spalte 'number' hinzugefügt
                IF @str <> ''
                    INSERT @tbl (number) VALUES(convert(int, @str))-- convert(Ziel-Type,Value)
    
                -- start wird auf das letzte bekannte end gesetzt
                SET @startpos = @endpos
    
                -- end position bekommt den charindex wo ein [LEERZEICHEN] gefunden wird
                SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr, @startpos + 1)
            END
            -- Loop 2
    
            -- dient dafür den letzten teil des strings zu selektieren
            SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos)--right(@string,anzahl der Zeichen) bsp.: right("abcdef",3) => "def"
        END
        -- Loop 1
    
        --wenn @leftover nach dem entfernen aller [LEERZEICHEN] nicht leer ist wird er zu int Convertiert und @tbl unter der Spalte 'number' hinzugefügt
        IF ltrim(rtrim(@leftover)) <> ''
            INSERT @tbl (number) VALUES(convert(int, @leftover))
    
        RETURN
    END
    
    
        -- ############################ WICHTIG ############################
        -- das is ein Beispiel wie man die Funktion benutzt
        --
        --CREATE    PROCEDURE get_product_names_iter 
        --      @ids varchar(50) AS
        --SELECT    P.ProductName, P.ProductID
        --FROM      Northwind.Products P
        --JOIN      iter_intlist_to_tbl(@ids) i ON P.ProductID = i.number
        --go
        --EXEC get_product_names_iter '9 12 27 37'
        --
        -- Funktion gefunden auf http://www.sommarskog.se/arrays-in-sql-2005.html
        -- dient zum übergeben einer Liste von Id's
        -- ############################ WICHTIG ############################
    

    【讨论】:

      【解决方案4】:

      如果非要选择id:

       DELETE FROM table WHERE id IN (SELECT id FROM somewhere_else)
      

      如果您已经认识他们(而且他们不是成千上万):

       DELETE FROM table WHERE id IN (?,?,?,?,?,?,?,?)
      

      【讨论】:

      • 如果有数千个,会对性能产生很大影响吗?我正在尝试删除一些重复项和一些我有 2-3 个重复项的地方。对于其他条目,我可能有几百或几千个。
      • 刚刚用 DELETE FROM user-access WHERE user-id=5 AND article-id IN (14,7,8) 确认了这一点,并想补充一点,数据库并不关心没有article-id 为 8 的行,它刚刚执行了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2022-01-26
      • 1970-01-01
      • 2015-11-30
      • 2019-09-28
      相关资源
      最近更新 更多