Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identifying repeated fields in SQL query

I have an SQL query that returns a column like this:

foo
-----------
1200
1200
1201
1200
1200
1202
1202
1202

It has already been ordered in a specific way, and I would like to perform another query on this result set to ID the repeated data like this:

foo    ID
----   ----
1200   1
1200   1
1201   2
1200   3
1200   3
1202   4
1202   4
1202   4

It's important that the second group of 1200 is identified as separate from the first. Every variation of OVER/PARTITION seems to want to lump both groups together. Is there a way to window the partition to only these repeated groups?

Edit: This is for Microsoft SQL Server 2012

like image 872
Joe Wilcoxson Avatar asked Jan 03 '14 16:01

Joe Wilcoxson


People also ask

How can we find duplicate records in a table?

One way to find duplicate records from the table is the GROUP BY statement. The GROUP BY statement in SQL is used to arrange identical data into groups with the help of some functions. i.e if a particular column has the same values in different rows then it will arrange these rows in a group.

How do I find duplicate names in SQL?

To find the duplicate Names in the table, we have to follow these steps: Defining the criteria: At first, you need to define the criteria for finding the duplicate Names. You might want to search in a single column or more than that. Write the query: Then simply write the query to find the duplicate Names.


2 Answers

Not sure this will be the fastest results...

select main.num, main.id from
(select x.num,row_number() 
over (order by (select 0)) as id 
from (select distinct num from num) x) main
join 
(select num, row_number() over(order by (select 0)) as ordering
 from num) x2 on 
x2.num=main.num
order by x2.ordering

Assuming the table "num" has a column "num" that contains your data, in the order-- of course num could be made into a view or a "with" for your original query.

Please see the following sqlfiddle

like image 128
Joe Love Avatar answered Nov 08 '22 01:11

Joe Love


Here is one way to do this without a CURSOR

-- Create a temporay table
DECLARE @table TABLE 
(
    SeqID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    foo INT,    
    id int null 
)


DECLARE @i INT
DECLARE @j INT
DECLARE @k INT
declare @tFoo INT
declare @oldFoo INT

SET @k = 0
set @oldFoo = 0



-- Insert data into the temporary table
INSERT INTO @table(foo) 
SELECT 1200
INSERT INTO @table(foo) 
SELECT 1200
INSERT INTO @table(foo) 
SELECT 1201
INSERT INTO @table(foo) 
SELECT 1200
INSERT INTO @table(foo) 
SELECT 1200
INSERT INTO @table(foo) 
SELECT 1202
INSERT INTO @table(foo) 
SELECT 1202
INSERT INTO @table(foo) 
SELECT 1202

-- Get the max and min SeqIDs to loop through
SELECT @i = MIN(SeqID) FROM @table
SELECT @j = MAX(SeqID) FROM @table


-- Loop through the temp table using the SeqID indentity column
WHILE (@i <= @j)
BEGIN
  SELECT @tFoo = foo FROM @table WHERE SeqID = @i

  if @oldFoo <> @tFoo
    set @k = @k + 1 

  update @table set id = @k where SeqID = @i    

  SET @oldFoo = @tFoo
  -- Increment the counter
  SET @i = @i + 1
END

SELECT * from @table
like image 37
unlimit Avatar answered Nov 08 '22 01:11

unlimit