deleting some rows leaving one.

  • given the table, I have a set of productcontrolID's that have many applicationID records.

    Given the set of productcontrolid's, how do I eliminate (delete) all but one row. While also deleting the applicationid (record) in the application table first because it is required.

    In a cursor I would just select the whole set, and skip the delete statement when the the productcontrolID changes.

    USE [PartsTrakStaging]

    GO

    /****** Object: Table [dbo].[ApplicationProduct] Script Date: 03/23/2009 08:45:00 ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    SET ANSI_PADDING ON

    GO

    CREATE TABLE [dbo].[ApplicationProduct](

    [ApplicationProductID] [int] IDENTITY(1,1) NOT NULL,

    [ApplicationID] [int] NOT NULL,

    [ProductControlID] [int] NOT NULL,

    [NumberRequired] [smallint] NULL,

    [Sequence] [smallint] NOT NULL,

    [SourceID] [int] NULL,

    [ChangedDate] [datetime] NULL,

    [ChangedType] [char](1) NULL,

    [ChangedMachineName] [varchar](50) NULL,

    CONSTRAINT [PK_ApplicationProduct2] PRIMARY KEY CLUSTERED

    (

    [ApplicationProductID] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET ANSI_PADDING OFF

    GO

    ALTER TABLE [dbo].[ApplicationProduct] WITH NOCHECK ADD CONSTRAINT [FK_ApplicationProduct_Application2] FOREIGN KEY([ApplicationID])

    REFERENCES [dbo].[Application] ([ApplicationID])

    GO

    ALTER TABLE [dbo].[ApplicationProduct] CHECK CONSTRAINT [FK_ApplicationProduct_Application2]

    GO

    ALTER TABLE [dbo].[ApplicationProduct] WITH NOCHECK ADD CONSTRAINT [FK_ApplicationProduct_ProductControl2] FOREIGN KEY([ProductControlID])

    REFERENCES [dbo].[ProductControl] ([ProductControlID])

    GO

    ALTER TABLE [dbo].[ApplicationProduct] CHECK CONSTRAINT [FK_ApplicationProduct_ProductControl2]

    GO

    /****** Object: Table [dbo].[Application] Script Date: 03/23/2009 08:48:34 ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    SET ANSI_PADDING ON

    GO

    CREATE TABLE [dbo].[Application](

    [ApplicationID] [int] NOT NULL,

    [ApplicationDescriptionID] [int] NOT NULL,

    [ApplicationCommentID] [int] NOT NULL,

    [NotRequired] [bit] NOT NULL,

    [Sequence] [smallint] NOT NULL,

    [sourceId] [int] NULL,

    [ChangedDate] [datetime] NULL,

    [ChangedType] [char](1) NULL,

    CONSTRAINT [PK_Application] PRIMARY KEY CLUSTERED

    (

    [ApplicationID] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET ANSI_PADDING OFF

    GO

    ALTER TABLE [dbo].[Application] WITH CHECK ADD CONSTRAINT [FK_Application_ApplicationComment] FOREIGN KEY([ApplicationCommentID])

    REFERENCES [dbo].[ApplicationComment] ([ApplicationCommentID])

    GO

    ALTER TABLE [dbo].[Application] CHECK CONSTRAINT [FK_Application_ApplicationComment]

    GO

    ALTER TABLE [dbo].[Application] WITH CHECK ADD CONSTRAINT [FK_Application_ApplicationDescription] FOREIGN KEY([ApplicationDescriptionID])

    REFERENCES [dbo].[ApplicationDescription] ([ApplicationDescriptionID])

    GO

    ALTER TABLE [dbo].[Application] CHECK CONSTRAINT [FK_Application_ApplicationDescription]

    GO

  • I'm not clear on what your criteria are for which ones to delete, but one way to get rid of all but one row from a set is like this:

    delete from dbo.ApplicationProduct

    where ApplicationProductID = @Param

    and ProductControlID not in

    (select min(ProductControlID)

    from dbo.ApplicationProduct

    where ApplicationProductID = @Param);

    Does that move you in the right direction?

    - Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
    Property of The Thread

    "Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon

  • sorta right, but:

    lets say this query gives me a set of the ones I want to delete.

    It certainly doesn't perform as well as the first part.

    SELECT DISTINCT Application.ApplicationID, NapaThirdParty.PN, Product.PartNumber, CategoryAAIAmap.GenCategoryID

    FROM ApplicationProduct WITH (nolock) INNER JOIN

    Application ON ApplicationProduct.ApplicationID = Application.ApplicationID INNER JOIN

    NapaThirdParty INNER JOIN

    Product ON NapaThirdParty.PN = Product.PartNumber INNER JOIN

    CategoryAAIAmap ON NapaThirdParty.[AAIA ID] = CategoryAAIAmap.[AAIA ID] ON ApplicationProduct.ProductControlID = Product.ProductControlID

    WHERE (Product.ProductLineID = 10290) and applicationproduct.applicationid not in (SELECT MIN(Application.ApplicationID) AS Expr1, ApplicationProduct.ProductControlID

    FROM ApplicationProduct WITH (nolock) INNER JOIN

    Application ON ApplicationProduct.ApplicationID = Application.ApplicationID INNER JOIN

    NapaThirdParty INNER JOIN

    Product ON NapaThirdParty.PN = Product.PartNumber INNER JOIN

    CategoryAAIAmap ON NapaThirdParty.[AAIA ID] = CategoryAAIAmap.[AAIA ID] ON ApplicationProduct.ProductControlID = Product.ProductControlID

    GROUP BY ApplicationProduct.ProductControlID)

  • If you have the cursor based code for doing this, it would help if you posted that as well. It will answer questions that will make rewriting in a set based manner easier.

  • I just finished code that should do that:

    private void button1_Click(object sender, EventArgs e)

    {

    sql = " SELECT distinct Application.ApplicationID, ApplicationProduct.ProductControlID ";

    sql += "FROM NapaThirdParty INNER JOIN ";

    sql += "Application INNER JOIN ";

    sql += "ApplicationProduct ON Application.ApplicationID = ApplicationProduct.ApplicationID INNER JOIN ";

    sql += "Product ON ApplicationProduct.ProductControlID = Product.ProductControlID ON NapaThirdParty.PN = Product.PartNumber ";

    sql += "WHERE (Product.ProductLineID = 10290)" ;

    DataTable dt1 = new DataTable();

    SqlConnection sconn = new SqlConnection(Properties.Settings.Default.ptstaging);

    SqlDataAdapter sda = new SqlDataAdapter();

    sda.SelectCommand = new SqlCommand();

    sda.SelectCommand.Connection = sconn;

    sda.UpdateCommand = new SqlCommand();

    sda.UpdateCommand.Connection = sconn;

    sda.SelectCommand.CommandText = sql;

    sda.Fill(dt1);

    string pcid = "";

    string appid;

    string sqldel1, sqldel2;

    foreach (DataRow dr in dt1.Rows)

    {

    if (pcid == dr["ProductControlID"].ToString())

    {

    sqldel1 = "delete from application where applicationid = " + dr["ApplicationID"].ToString();

    sda.UpdateCommand.CommandText = sqldel1;

    sda.UpdateCommand.ExecuteNonQuery();

    sqldel2 = "delete from applicationproduct where applicationid = " + dr["ApplicationID"].ToString();

    sda.UpdateCommand.CommandText = sqldel2;

    sda.UpdateCommand.ExecuteNonQuery();

    }

    pcid = dr["productcontrolid"].ToString();

    }

    }

  • There's a DELETE...FROM lurking in here:

    SELECT DISTINCT a.ApplicationID, n.PN, p.PartNumber, c.GenCategoryID

    FROM ApplicationProduct ap (nolock)

    INNER JOIN Application a

    ON ap.ApplicationID = a.ApplicationID

    INNER JOIN Product p

    ON ap.ProductControlID = p.ProductControlID

    INNER JOIN NapaThirdParty n

    ON n.PN = p.PartNumber

    INNER JOIN CategoryAAIAmap c

    ON n.[AAIA ID] = c.[AAIA ID]

    WHERE p.ProductLineID = 10290

    AND ap.applicationid NOT IN

    (SELECT MIN(a.ApplicationID) AS Expr1, ap.ProductControlID

    FROM ApplicationProduct ap WITH (nolock)

    INNER JOIN Application a

    ON ap.ApplicationID = a.ApplicationID

    INNER JOIN Product p

    ON ap.ProductControlID = p.ProductControlID

    INNER JOIN NapaThirdParty n

    ON n.PN = p.PartNumber

    INNER JOIN CategoryAAIAmap c

    ON n.[AAIA ID] = c.[AAIA ID]

    GROUP BY ap.ProductControlID)

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Chris Morris (3/23/2009)


    There's a DELETE...FROM lurking in here:

    SELECT DISTINCT a.ApplicationID, n.PN, p.PartNumber, c.GenCategoryID

    FROM ApplicationProduct ap (nolock)

    INNER JOIN Application a

    ON ap.ApplicationID = a.ApplicationID

    INNER JOIN Product p

    ON ap.ProductControlID = p.ProductControlID

    INNER JOIN NapaThirdParty n

    ON n.PN = p.PartNumber

    INNER JOIN CategoryAAIAmap c

    ON n.[AAIA ID] = c.[AAIA ID]

    WHERE p.ProductLineID = 10290

    AND ap.applicationid NOT IN

    (SELECT MIN(a.ApplicationID) AS Expr1, ap.ProductControlID

    FROM ApplicationProduct ap WITH (nolock)

    INNER JOIN Application a

    ON ap.ApplicationID = a.ApplicationID

    INNER JOIN Product p

    ON ap.ProductControlID = p.ProductControlID

    INNER JOIN NapaThirdParty n

    ON n.PN = p.PartNumber

    INNER JOIN CategoryAAIAmap c

    ON n.[AAIA ID] = c.[AAIA ID]

    GROUP BY ap.ProductControlID)

    problem with this is the last subquery seems to take forever on the server.

    Take a look at the code posted above, and work it as setbased. Should be simple right?

    I seem to recall something of "it's easier" nature to setbase solutions. However when it comes right down to it, I am having doubts.

  • foxjazz (3/23/2009)


    problem with this is the last subquery seems to take forever on the server.

    Take a look at the code posted above, and work it as setbased. Should be simple right?

    I seem to recall something of "it's easier" nature to setbase solutions. However when it comes right down to it, I am having doubts.

    Do you need anything other than MIN(a.ApplicationID) in order to identify the rows you need to delete? Which table do you want to delete from?

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Try this in a test copy of the database, or wrapped in a transaction you can roll back.

    DELETE

    ApplicationProduct

    FROM

    dbo.ApplicationProduct

    INNER JOIN dbo.Application

    ON ApplicationProduct.ApplicationID = Application.ApplicationID

    INNER JOIN dbo.Product

    ON ApplicationProduct.ProductControlID = Product.ProductControlID

    WHERE

    (Product.ProductLineID = 10290)

    and

    applicationproduct.applicationid not in

    (SELECT

    MIN(Application.ApplicationID)

    FROM

    ApplicationProduct

    GROUP BY

    ApplicationProduct.ProductControlID);

    See if that'll do what you need.

    If it gets the end result you need, but it's too slow, post the execution plan.

    - Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
    Property of The Thread

    "Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon

  • Since there is a constraint, I have to delete the applicationid from the application table first, then delete it from the applicationproduct table.

    As seen in the code above.

  • First question, does the following query return the correct result set that you are deleting items based on?

    SELECT distinct

    Application.ApplicationID,

    ApplicationProduct.ProductControlID

    FROM

    [Application]

    INNER JOIN [ApplicationProduct]

    ON Application.ApplicationID = ApplicationProduct.ApplicationID

    INNER JOIN [Product]

    ON ApplicationProduct.ProductControlID = Product.ProductControlID

    INNER JOIN NapaThirdParty

    ON NapaThirdParty.PN = Product.PartNumber

    WHERE

    (Product.ProductLineID = 10290)

  • Also, looking at your initial post, you only provided the DDL for two of the tables in the query. Really could use the DDL for the other two tables. Also, some test data and expected results would really allow us to test any code before posting it back on this thread.

  • foxjazz (3/23/2009)


    Since there is a constraint, I have to delete the applicationid from the application table first, then delete it from the applicationproduct table.

    As seen in the code above.

    Do you have to delete "all but one row" from that table too, or is it all rows that fit certain criteria? Or am I getting the tables backwards?

    - Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
    Property of The Thread

    "Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon

  • Lynn Pettis (3/23/2009)


    First question, does the following query return the correct result set that you are deleting items based on?

    SELECT distinct

    Application.ApplicationID,

    ApplicationProduct.ProductControlID

    FROM

    [Application]

    INNER JOIN [ApplicationProduct]

    ON Application.ApplicationID = ApplicationProduct.ApplicationID

    INNER JOIN [Product]

    ON ApplicationProduct.ProductControlID = Product.ProductControlID

    INNER JOIN NapaThirdParty

    ON NapaThirdParty.PN = Product.PartNumber

    WHERE

    (Product.ProductLineID = 10290)

    yes the following query has the resultset of all the applicationid save one that I need to have deleted.

    If you want the other 2 tables here they are:

    USE [PartsTrakStaging]

    GO

    /****** Object: Table [dbo].[NapaThirdParty] Script Date: 03/23/2009 12:03:43 ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    SET ANSI_PADDING ON

    GO

    CREATE TABLE [dbo].[NapaThirdParty](

    [AAIA ID] [int] NULL,

    [Description] [varchar](50) NULL,

    [PN] [varchar](50) NULL

    ) ON [PRIMARY]

    GO

    SET ANSI_PADDING OFF

    GO

    USE [PartsTrakStaging]

    GO

    /****** Object: Table [dbo].[Product] Script Date: 03/23/2009 12:03:53 ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    SET ANSI_PADDING ON

    GO

    CREATE TABLE [dbo].[Product](

    [ProductID] [int] IDENTITY(1,1) NOT NULL,

    [ProductLineID] [int] NOT NULL,

    [PartNumber] [nvarchar](50) NOT NULL,

    [SearchNumber] [nvarchar](50) NOT NULL,

    [ProductNumber] [nvarchar](50) NULL,

    [ProductStatusID] [int] NOT NULL,

    [DateStatusChange] [smalldatetime] NULL,

    [Publish] [bit] NULL,

    [ProductControlID] [int] NULL,

    [NumberRequired] [smallint] NOT NULL,

    [BasePrice] [money] NULL,

    [MPG] [int] NULL,

    [UPC] [varchar](50) NULL,

    [PolkFits] [int] NULL,

    [PolkHits] [int] NULL,

    [Rank] [int] NULL,

    [Code] [char](1) NULL,

    [DefaultUnitID] [int] NULL,

    [ChangedDate] [datetime] NULL,

    [ChangedType] [char](1) NULL,

    [Transmit] [int] NULL,

    CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED

    (

    [ProductID] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],

    CONSTRAINT [IX_Product_1] UNIQUE NONCLUSTERED

    (

    [ProductLineID] ASC,

    [PartNumber] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET ANSI_PADDING OFF

    GO

    ALTER TABLE [dbo].[Product] WITH NOCHECK ADD CONSTRAINT [FK_Product_ProductControl] FOREIGN KEY([ProductControlID])

    REFERENCES [dbo].[ProductControl] ([ProductControlID])

    GO

    ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductControl]

    GO

    ALTER TABLE [dbo].[Product] WITH NOCHECK ADD CONSTRAINT [FK_Product_ProductLine] FOREIGN KEY([ProductLineID])

    REFERENCES [dbo].[ProductLine] ([ProductLineID])

    GO

    ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductLine]

    GO

    ALTER TABLE [dbo].[Product] WITH NOCHECK ADD CONSTRAINT [FK_Product_ProductStatus] FOREIGN KEY([ProductStatusID])

    REFERENCES [dbo].[ProductStatus] ([ProductStatusID])

    GO

    ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductStatus]

    GO

  • Good, but still lacking. Some sample data and expected results would be the icing on the cake. That would allow us to validate our code before posting back.

    Please help us help you.

Viewing 15 posts - 1 through 15 (of 21 total)

You must be logged in to reply to this topic. Login to reply