Removing rows , if they have duplicate - sql-server

Lets suppose I have a following table in sql server 2008.
Column1 Column2 Column3
1 2 1
1 2 1
5 1 1
3 2 1
3 2 1
4 1 1
The output should be following
Column1 Column2 Column3
5 1 1
4 1 1
If a row has a duplicates present then , the original row and all the duplicate rows are to be deleted.If a row doesnot have any duplicates. Then it is kept. How can i achieve this?

Try like this,
DECLARE #Table TABLE (
Column1 INT
,Column2 INT
,Column3 INT
)
INSERT INTO #Table
(Column1,Column2,Column3)
VALUES
(1,2,1),
(1,2,1),
(5,1,1),
(3,2,1),
(3,2,1),
(4,1,1)
SELECT *
FROM #Table
DELETE t1
FROM #Table t1
INNER JOIN (
SELECT Column1
,Column2
,Column3
FROM #Table t
GROUP BY Column1
,Column2
,Column3
HAVING count(*) > 1
) t2 ON t1.column1 = t2.Column1
AND t1.column2 = t2.column2
AND t1.column3 = t2.column3
SELECT * FROM #Table

Related

Recursive Top to Bottom Parent and it's Child

declare #table as table
(
Id int,
ParentId int
)
insert into #table
values (1 , null),(2,1),(3,1),(4,2),(5,2),(6,3),(7,3)
;with cte
as (select Id,ParentId,1 as [level]
from #table as t
where ParentId is null
UNION ALL
select t.Id,t.ParentId , cte.level + 1
from #table as t
join cte
on t.ParentId = cte.Id)
select *
from cte
Id
ParentId
Level
1
NULL
1
2
1
2
3
1
2
6
3
3
7
3
3
4
2
3
5
2
3
I want to get Top to Bottom Parent -> it's all descendants
and again Top to Bottom Parent -> it's descendants
but I am unable to get expected output using above query
expected output vertically in table
Id 1 -> 2 -> 4 -> 5
Id 1 -> 3 -> 6 -> 7
expected output
Id
ParentId
Level
1
NULL
1
2
1
2
4
2
3
5
2
3
1
NULL
1
3
1
2
6
3
3
7
3
3
A tree Starts from 1 and goes to bottom to find it's all child
1 -> 2 -> 4 -> 5
again tree Starts from 1 and goes to bottom to find it's all child
1 -> 3 -> 6 -> 7
declare #table as table
(
Id int,
ParentId int
)
declare #cte as table
(
Id int,
ParentId int
)
declare #output as table
(
Id int,
ParentId int
)
insert into #table
values (1,null),(2,1),(3,1),(4,2),(5,2),(6,3),(7,3)
declare #id int
declare #parentid int
;with cte
as (select Id,ParentId
from #table as t
where ParentId is null
UNION ALL
select t.Id,t.ParentId
from #table as t
join cte
on t.ParentId = cte.Id)
insert into #cte
select *
from cte
declare #start int = 1
declare #end int = (select count(ParentId) from #cte where ParentId= (select Id from #cte where ParentId is null))
while(#start <= #end)
begin
select top 1 #id = Id ,#parentid=ParentId from #cte where ParentId = (select Id from #cte where ParentId is null)
if(#id > 0 )
begin
insert into #output
select * from #cte where ParentId is null
insert into #output values (#id,#parentid)
delete from #cte where Id = #id and ParentId = #parentid
insert into #output
select * from #cte where ParentId = #id
delete from #cte where Id in (select Id from #cte where ParentId = #id)
end
set #start+=1
end
select * from #output
thank you guys for your help i figured it out by myself.
it would be nice if any of you guys improve my answer, it is not best solution but currently it is what it is

SQL QUERY to Start Numbering Row_ID Everytime a Unique number Is Found

is there any possible way to get a unique id for similar kind of number for example
H_ID ROW_ID
1 1
1 2
1 3
2 1
2 2
3 1
3 2
AS SHOWN 1 IS REPEATED 3 TIMES SO NUMBERS ARE 1,2,3 AND THEN AGAIN STARTS WITH 1
Try it's
declare #table table (h_id int)
insert into #table
select 1
insert into #table
select 1
insert into #table
select 1
insert into #table
select 2
insert into #table
select 2
insert into #table
select 3
insert into #table
select 3
select h_id,d
from (select row_number() over(partition by h_id order by h_id ) as d,*
from #table) as source
Reference https://learn.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql
You can use ROW_NUMBER() window function
CREATE TABLE #ROW_TEST
(
H_ID INT
)
INSERT INTO #ROW_TEST
SELECT 1
UNION ALL SELECT
1
UNION ALL SELECT
1
UNION ALL SELECT
2
UNION ALL SELECT
2
UNION ALL SELECT
3
UNION ALL SELECT
3
SELECT H_ID,ROW_NUMBER() OVER (PARTITION BY H_ID ORDER BY H_ID) FROM #ROW_TEST

SQL SUM Values need and then AVG of 2 Tables

From this it is possible for the following :
TABLE 1
Id | final | Date
------------------
1 236 02-11-14
2 10 07-01-12
3 58 09-02-10
TABLE 2
Id | final | Date
------------------
1 330 02-11-14
2 5 07-01-12
3 100 09-02-10
ADD both Table 1 and Table 2 Sum'd values(column final), and then work out the AVG number from this and create this as another column average, THEN if table2 for example SUM'd original amount (before the AVG) is higher than Table 1 SUM'd amount create another column and print in that column 'Tbl2 has the higher amount' and vise verser if table 1 had the higher amount.
End result Column wise table would look like this :
|tb1_final_amount|tb2_final_amount|Avg_Amount|Top_Score_tbl
|tb1_final_amount|tb2_final_amount|Avg_Amount|Top_Score_tbl
304 435 369.5 tb2 has highest score
This is one way (of many) to do this. You can sum up the two tables and use them as derived tables in a query like so:
select
tb1_final_amount,
tb2_final_amount,
(tb1_final_amount+tb2_final_amount)/2.0 as Avg_Amount,
case
when tb1_final_amount < tb2_final_amount then 'tb2 has highest score'
else 'tb1 has highest score'
end as Top_Score_tbl
from
(select SUM(final) as tb1_final_amount from TABLE1) t1,
(select SUM(final) as tb2_final_amount from TABLE2) t2
This does the trick!:
--SET UP Table1
CREATE TABLE Table1 (ID INT, final INT, [Date] DATETIME)
INSERT Table1 VALUES (1, 236, '20141102')
INSERT Table1 VALUES (2, 10, '20120107')
INSERT Table1 VALUES (3, 58, '20100209')
--SET UP Table2
CREATE TABLE Table2 (ID INT, final INT, [Date] DATETIME)
INSERT Table2 VALUES (1, 330, '20141102')
INSERT Table2 VALUES (2, 5, '20120107')
INSERT Table2 VALUES (3, 100, '20100209')
-- Query
SELECT
SUM(CASE WHEN t.TableName = 'Table1' THEN T.final
ELSE 0
END) AS tb1_final_amount,
SUM(CASE WHEN t.TableName = 'Table2' THEN T.final
ELSE 0
END) AS tb2_final_amount,
AVG(T.final) AS Avg_Amount,
ISNULL((
SELECT
'Table1'
FROM
Table1 T1
WHERE
SUM(CASE WHEN t.TableName = 'Table1' THEN T.final
ELSE 0
END) > SUM(CASE WHEN t.TableName = 'Table2' THEN T.final
ELSE 0
END)
), 'Table2')
FROM
(
SELECT
'Table1' AS TableName,
final
FROM
Table1
UNION ALL
SELECT
'Table2',
final
FROM
Table2
) AS T

How do I get distinct COUNT in pivot?

I have a following table:
State LAB GROUP DATE CODE ID
UP A I 1-Jan 1 345
UP R S 1-Feb 1 456
UP A S 1-Jan 2 567
DL R S 1-Feb 3 678
DL T S 1-Jan 1 789
DL A S 1-Jan 2 900
MN T S 1-Jan 3 1011
MN R I 1-Feb 1 1122
MN S I 1-Feb 2 1233
I need a pivot table of following type:
STATE A R T TOTAL
UP 2 1 0 3
DL 1 1 1 3
MN 0 1 1 2
DISTINCT COUNT OF ID FOR EACH LAB FOR EACH STATE.
I then need the pivot tables filtered for following columns:
GROUP
DATE
CODE
So 1st table will have the pivot table above counting only those records which have GROUP=S
2nd table will have the pivot table above counting only those records which have CODE=1
and so on, I wish to put multiple conditions. and generate several tables one by one and export them.
If this is possible in SQL please let me know! I ruled out excel vba due to the size of table (source table will have 800,000 records approx).
Try this :-
Select [State],[A],[R],[T],Total = [A] + [R]+ [T]
from
(
Select [State],
[A] = Sum(Case when LAB='A' then 1 else 0 END) ,
[R] = Sum(Case when LAB='R' then 1 else 0 END) ,
[T] = Sum(Case when LAB='T' then 1 else 0 END)
from YourTable
group by [State]
)a
SQL FIDDLE
CREATE TABLE #t(States VARCHAR(10),LAB VARCHAR(5),GROUPs VARCHAR(5),DATEs VARCHAR(10),CODE INT,ID INT)
INSERT INTO #t values('UP','A','I','1-Jan',1,345)
INSERT INTO #t values('UP','R','S','1-Feb',1,456)
INSERT INTO #t values('UP','A','S','1-Jan',2,567)
INSERT INTO #t values('DL','R','S','1-Feb',3,678)
INSERT INTO #t values('DL','T','S','1-Jan',1,789)
INSERT INTO #t values('DL','A','S','1-Jan',2,900)
INSERT INTO #t values('MN','T','S','1-Jan',3,1011)
INSERT INTO #t values('MN','R','I','1-Feb',1,1122)
INSERT INTO #t values('MN','S','I','1-Feb',2,1233)
SELECT States,ISNULL(A,0) A,ISNULL(R,0) R,ISNULL(T,0) T,ISNULL(A,0)+ISNULL(R,0)+ISNULL(T,0) total
FROM
(
SELECT States,LAB,Count(ID) AS cnt FROM #t GROUP BY States,LAB /*apply GROUP DATE CODE condition here*/
) AS PVT
PIVOT(MAX(cnt) FOR LAB IN (A,R,T)) pvt
Another solution using PIVOT :
WITH PivotInUse AS (
SELECT state,lab,COUNT(*) AS cnt
FROM YourTable
GROUP BY state,lab
)
SELECT STATE
,COALESCE([A], 0) AS A
,COALESCE([R], 0) AS R
,COALESCE([T], 0) AS T
,COALESCE([A], 0) + COALESCE([R], 0) + COALESCE([T], 0) AS TOTAL
FROM PivotInUse
PIVOT(SUM(cnt) FOR lab IN ([A],[R],[T])) AS p;
Your sample table
SELECT * INTO #TEMP FROM
(
SELECT 'UP' [State],'A' LAB,'I' [GROUP],'1-Jan' [DATE],1 CODE,345 ID
UNION ALL
SELECT 'UP','R','S','1-Feb',1,456
UNION ALL
SELECT 'UP','A','S','1-Jan',2,567
UNION ALL
SELECT 'DL','R','S','1-Feb',3,678
UNION ALL
SELECT 'DL','T','S','1-Jan',1,789
UNION ALL
SELECT 'DL','A','S','1-Jan',2,900
UNION ALL
SELECT 'MN','T','S','1-Jan',3,1011
UNION ALL
SELECT 'MN','R','I','1-Feb',1,1122
UNION ALL
SELECT 'MN','S','I','1-Feb',2,1233
)TAB
Now you need to get the distinct count of each state and get the sum as the result to show Total
in pivoted result.
SELECT DISTINCT [State],LAB,SUM(CNT) CNT
INTO #NEWTABLE
FROM
(
SELECT DISTINCT
[State],LAB,
CASE WHEN [State] IS NULL THEN NULL ELSE COUNT([State]) OVER(PARTITION BY [State],LAB) END CNT
FROM #TEMP
)TAB
GROUP BY [State],LAB
WITH ROLLUP
Now we need to get the distinct columns for pivot(#cols) and columns to identify and replace null with zero in pivot(#NullToZeroCols)
DECLARE #cols NVARCHAR (MAX)
DECLARE #NullToZeroCols NVARCHAR (MAX)
SET #cols = SUBSTRING((SELECT DISTINCT ',['+LAB+']' FROM #NEWTABLE GROUP BY LAB FOR XML PATH('')),2,8000)
SET #NullToZeroCols = SUBSTRING((SELECT DISTINCT ',ISNULL(['+LAB+'],0) AS ['+LAB+']'
FROM #NEWTABLE GROUP BY LAB FOR XML PATH('')),2,8000)
Join the pivotted query with the #NEWTABLE to get the Total for each State
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT P.State,' + #NullToZeroCols + ',T2.CNT TOTAL FROM
(
SELECT DISTINCT [State],LAB,CNT FROM #NEWTABLE
) x
PIVOT
(
SUM(CNT)
FOR [LAB] IN (' + #cols + ')
) p
JOIN #NEWTABLE T2 ON P.[STATE]=T2.[STATE]
WHERE P.State IS NOT NULL AND T2.LAB IS NULL AND T2.[STATE] IS NOT NULL;'
EXEC SP_EXECUTESQL #query
Here is your result
Here is the SQLFiddle http://sqlfiddle.com/#!3/c2588/1 (If it shows any error while loading the page, just click RUNSQL, it will work)
Now if you want to get the result as you said DISTINCT COUNT OF ID FOR EACH LAB FOR EACH STATE, just change
OVER(PARTITION BY [State],LAB)
to
OVER(PARTITION BY [State],LAB,Id)
which will show the following result after executing the pivot query

SQL Server 2008 : TSQL, select same data for different times based on column value

I am using mssql 2008 R2,
i have below structure
create table #temp (
product int,
[order] int,
ord_qnty int
)
insert #temp
select 10 ,3,4
now, if ord_qnty is 4 , i want to select same product,order four times but in all four rows thevalue of ord_qnty should be 1 , i.e.
out put should be
Product order ord_qnty
10 3 1
10 3 1
10 3 1
10 3 1
If you have a numbers table, you can use that. If not, you can generate one:
;with Numbers(n) as (
select ROW_NUMBER() OVER (ORDER BY object_id) from sys.objects
)
select product,[order],1 as ord_qnty
from #temp t inner join Numbers num
on t.ord_qnty >= num.n
(In my nearly empty scratch database, the ROW_NUMBER() generates 77 rows. If that's not going to be enough, you can introduce cross-joins or use other tricks to generate more numbers, or you can create and populate a permanent numbers table)
Try this one -
Query:
DECLARE #temp TABLE
(
product INT
, [order] INT
, ord_qnty INT
)
INSERT #temp(product, [order], ord_qnty)
SELECT 10, 3, 4
SELECT
t.product
, t.[order]
, ord_qnty = 1
FROM #temp t
JOIN [master].dbo.spt_values sv ON t.ord_qnty > sv.number
WHERE sv.[type] = 'p'
SELECT
t.product
, t.[order]
, ord_qnty = 1
FROM #temp t
JOIN (
SELECT number = ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM sys.system_parameters p
) sv ON t.ord_qnty >= sv.number
Output:
product order ord_qnty
----------- ----------- -----------
10 3 1
10 3 1
10 3 1
10 3 1
Query Cost:
For any "millions value":
SET NOCOUNT ON;
DECLARE #numbers TABLE (number INT)
DECLARE #temp TABLE
(
product INT
, [order] INT
, ord_qnty INT
)
INSERT #temp(product, [order], ord_qnty)
SELECT 10, 3, 4
DECLARE
#i BIGINT = 1
, #max BIGINT = (
SELECT MAX(ord_qnty)
FROM #temp
)
WHILE (#i <= #max) BEGIN
INSERT INTO #numbers (number)
VALUES (#i), (#i+1), (#i+2), (#i+3), (#i+4), (#i+5), (#i+6), (#i+7), (#i+8), (#i+9)
SELECT #i += 10
END
SELECT
t.product
, t.[order]
, ord_qnty = 1
FROM #temp t
CROSS JOIN (
SELECT *
FROM #numbers
WHERE number < #max + 1
) t2

Resources