2010-10-28 38 views
30

quiero hacer algo como esto:¿Cómo elimino varias filas con diferentes ID?

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

¿Cómo puedo hacer eso?

+0

¿Qué base de datos? En la mayoría, lo que describes debería funcionar. – Thilo

+0

¿Cómo no puedes hacer eso? Lo que no funciona? ¿Qué base de datos estás usando? Oracle/MySql/SqlServer? – Fermin

+0

Aclare dónde obtendrá la lista de Id. Desde ..., sí, es posible eliminar la Id. De ... –

Respuesta

80

Si usted tiene que seleccionar el ID:

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

Si ya los conoce (y que no está en los miles):

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

Si son miles, ¿tendrá un impacto mucho en el rendimiento? Estoy tratando de eliminar algunos duplicados y algunos lugares que tengo entre 2-3 duplicados. Para otras entradas, podría tener algunos cientos o miles. – Zeliax

0

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

si wane haz esto con muchos Id. puedes usar un function que crea una tabla temporal donde podrás BORRAR DE la selección

forma en que la consulta podría ser:

-- 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)) 

aquí es la función:

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 ############################ 
1
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); 
+0

Debe formatear su código seleccionándolo y presionando ctrl-k. Además, ayuda a proporcionar alguna explicación, tal vez sugiriendo qué problema tenía el código en la pregunta (en todo caso). –

+0

Esta es una gran solución: 'DELETE FROM [TableName] WHERE [ColumnName] IN (SELECT [ColumnName] FROM [TableName] GROUP BY [ColumnName] HAVING COUNT ([ColumnName])> 1);' – dakab

-4
  • Usted puede hacer esto.

    CREATE PROC [dbo]. [Sp_DELETE_MULTI_ROW]
    @CODE XML , @ ERRFLAG CHAR (1) = '0' SALIDA

AS

NOCOUNT SET EN
SET TRANSACTION NIVEL DE AISLAMIENTO LEÍDO INCOGIDO

ELIMINAR tb_SampleTest DONDE CÓDIGO EN ()SELECT Item.value (' ' 'VARCHAR (20)') de @ CODE.nodes (' RecordList/ID') AS x (punto) )

IF @@ ROWCOUNT = 0 SET @ ERRFLAG = 200

SET NOCOUNT OFF

  • < 'RecordList'> < 'ID'> 1 < '/ ID> < 'ID'> 2 <'/ID> < '/ RecordList' >
Cuestiones relacionadas