|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Saturday, May 04, 2013 11:13 AM
Points: 9,855,
Visits: 9,374
|
|
|
|
|
|
SSC-Dedicated
           
Group: General Forum Members
Last Login: Today @ 10:02 AM
Points: 32,893,
Visits: 26,768
|
|
What an amazing article! Covers most everything from womb-to-tomb for such an "impossible" delete. I remember being amazed when Barry first posted his solution on the original thread. I'm even more amazed that he wove in some of the techniques used in the old days and took the time to explain how each byte of memory was cherished which made these types of methods absolutely necessary.
Well done, Barry!
--Jeff Moden "RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".
First step towards the paradigm shift of writing Set Based code: Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."
For better, quicker answers on T-SQL questions, click on the following... http://www.sqlservercentral.com/articles/Best+Practices/61537/
For better answers on performance questions, click on the following... http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Tuesday, August 14, 2012 12:51 AM
Points: 1,
Visits: 10
|
|
Nice Article. I learned a lot. But for this problem there may be a shorter/ simpler solution :
--======1 Insert Records We want to have Insert into SOURCE(Name, Age, Sex) Select Name , Age , Case Sex When 'M' Then 'N' Else 'G' End From SOURCE Group By Name, Age, Sex Having Count (*) > 1
--======2: Remove the old rows Delete from SOURCE Where Sex In ('M','F')
--======3: Update the inserted records accordingly Update SOURCE Set Sex = CASE Sex When 'N' Then 'M' Else 'F' End
Both of us depend on the case that Sex column has one of two values. If that is not the case then solution would be appending a character / string that does not exist in the original data (ex '~~~~~') in first step. Delete the ones that does not have appended string in the second step. Remove appended string in the third step.
|
|
|
|
|
Old Hand
      
Group: General Forum Members
Last Login: Tuesday, April 09, 2013 4:24 AM
Points: 318,
Visits: 1,172
|
|
eerkan - I don't think your solution will give what the OP wanted. It'll collapse all duplicated rows into a single row, whereas the OP wanted to retain all dupes as seperate rows.
Great article btw - RBarryYoung bringing back the old skool :P
Regards,
Jacob
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Wednesday, April 24, 2013 5:02 AM
Points: 2,365,
Visits: 1,825
|
|
great article!!
"Keep Trying"
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Thursday, March 14, 2013 4:15 AM
Points: 3,240,
Visits: 4,960
|
|
GREAT ARTICLE...
Alot of learning points in it...
My First thought, I would have gone for cursors to solve the issue. Secondly, I would certainly NOT go for the conversions as used in the article (who cares about bit and bytes nowdays...). But one MUST know the way to accomplish the task using the limited and KNOWN resources whic makes the solution in the article THE BEST in all aspects...
BRAVO...
Atif Sheikh
---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sometimes, winning is not an issue but trying. You can check my BLOG here
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Thursday, March 14, 2013 4:15 AM
Points: 3,240,
Visits: 4,960
|
|
eerkan... your solution misses one record
Try again...:D
Atif Sheikh
---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sometimes, winning is not an issue but trying. You can check my BLOG here
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Sunday, April 14, 2013 8:55 AM
Points: 1,383,
Visits: 1,212
|
|
Hmm, my curiousity is piqued... The solution presented is quite interesting, but I believe the purported interest in bits and bytes is a little exaggerated, as the solution is still quite expensive (rewrites an entire column in a single update statement, and rewrites/deletes the bulk of the data if there are many duplicates - needing up to almost double the original storage space to complete). So I'm quite curious:
What would the most efficient way of addressing this problem be? (using least memory and / or using least I/O, especially on a very large data set; also consider whether the data can still be accessed during the update process)
This should be quite easy to test, given a few hours to create a large (GB-sized?) data set and try out a few different approaches...
It seems a problem that many more people are likely to face nowadays - powerful hardware, very robust systems that can remain online as you do things like add columns, but extremely large amounts of data (many gigabytes) and no maintenance time / downtime available!
http://poorsql.com for T-SQL formatting: free as in speech, free as in beer, free to run in SSMS or on your version control server - free however you want it.
|
|
|
|
|
Old Hand
      
Group: General Forum Members
Last Login: Friday, May 03, 2013 2:54 AM
Points: 328,
Visits: 1,848
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Today @ 4:00 AM
Points: 533,
Visits: 2,285
|
|
Surely this is the simplest solution? (be warned of a nasty catch when creating these 'quirky updates'. the order of execution of the update is -variable assignments first then column assignments-both left to right!)
--create the sample table DECLARE @Sample TABLE (TheName VARCHAR(4),Identifier INT, sex VARCHAR(1)) INSERT INTO @Sample (TheName,Identifier,Sex) SELECT 'ABC', 24, 'M' UNION ALL SELECT 'ABC', 24,'M' UNION ALL SELECT 'LMN', 27, 'M' UNION ALL SELECT 'LMN', 27, 'M' UNION ALL SELECT 'LMN', 27, 'M' UNION ALL SELECT 'PQRS', 25, 'F' UNION ALL SELECT 'XYZ', 24, 'M' UNION ALL SELECT 'XYZ', 25, 'M' --@Sex variable only used to force the order of execution of the update DECLARE @hash VARCHAR(80), @sex VARCHAR(1) UPDATE @sample SET @sex=Sex = CASE WHEN COALESCE(@hash,'') <>TheName+CONVERT(VARCHAR(5),Identifier)+sex THEN 'd' ELSE SEX END, @hash= TheName+CONVERT(VARCHAR(5),Identifier)+sex
DELETE FROM @sample WHERE sex='d' SELECT * FROM @sample
Best wishes,
Phil Factor Simple Talk
|
|
|
|