I am trying to eliminate duplicate based on combination of three columns on the same table with some filter conditions through two different approaches but for some reason the result of both are queries are not coming as same.
Query 1:
select count(*)
from (
select distinct
SERIAL_NBR,
MAC_ADDR,
UNIT_ADDR
from TGT_DEVICE_DETAILS
where MODEL_ID = 'ABC' and REC_CREATE_DT_KEY = 20191130
);
Result - 66181
Query 2:
select count(*) from (
select
xi.*,
row_number() over (
partition by xi.SERIAL_NBR,xi.MAC_ADDR,xi.UNIT_ADDR
order by test_date_m desc
) rownumber
from TGT_DEVICE_DETAILS xi
)
where
rownumber = 1
and REC_CREATE_DT_KEY = 20191130
and MODEL_ID = 'ABC';
Result - 65495
Shouldn't the result of both the queries be the same ? Would be great if someone can tell me what am i doing wrong ?
Thanks,
Kavin
The second query has conditions REC_CREATE_DT_KEY = 20191130 and MODEL_ID = 'ABC' in the outer query, while in the first query these are in the inner query.
Move the conditions to the inner query and you should get the same results:
select count(*) from (
select
xi.*,
row_number() over (
partition by SERIAL_NBR, MAC_ADDR, UNIT_ADDR
order by TEST_DATE_M desc
) rownumber
from TGT_DEVICE_DETAILS xi
WHERE REC_CREATE_DT_KEY = 20191130 and MODEL_ID = 'ABC'
)
where rownumber = 1;
I am using SQL Server.
I have a table with the following design:
ID bigint
Number varchar(50)
Processed int
I have a lot of duplicates in the Number column
I want to delete all repeated Numbers, and keep the Number where processed=1
For Example if I have
Number --- Processed
111 --- 0
111 --- 0
111 --- 1
I want to delete all and keep the last one
Any help would be appreciated
Here is one method:
with todelete as (
select t.*,
row_number() over (partition by number order by processed desc) as seqnum
from table t
)
delete from todelete
where seqnum > 1;
The row_number() enumerates the rows, using the processed as a priority. The logic ensures that exactly one row remains, even if none have processed = 1.
If you are just trying to delete the rows where number equals 111 and processed does not equal 1 you can do:
delete from <table>
where
Number = 111 and
Processed <> 1
Assuming the ID is sequential and you want to keep the last row for each Number you can do:
delete from <table> t
left join (
select
MAX(ID) filter_ID
from <table>
group by
Number
) filter on
t.ID = filter.filter_ID
where
filter.filter_ID is null
to keep at least one row per Number giving priority to Processed = 1
delete from <table> t
left join (
select
ID
from (
select
ROW_NUMBER() OVER (
PARTITION BY
Number
ORDER BY
Processed DESC,
ID DESC
) last_R,
ID
from <table>
) filter
where
last_R = 1
) filter on
t.ID = filter.filter_ID
where
filter.filter_ID is null
Here is how I would approach this problem:
DECLARE #NUM VARCHAR(50)
DECLARE #TAB TABLE
(
NUMBER VARCHAR(50)
)
INSERT INTO #TAB
SELECT number, from <table> where processed = 0 GROUP BY number HAVING COUNT(number) > 1
DECLARE #IDToKEEP TABLE
(
id INT
)
WHILE (SELECT COUNT(*) FROM #TAB) > 0
BEGIN
SELECT TOP 1 #NUM = number FROM #TAB
INSERT INTO #IDToKEEP
SELECT TOP 1 id FROM <table> WHERE number = #NUM
DELETE FROM #TAB WHERE number = #NUM
END
DELETE FROM <table> WHERE processed = 0 AND number IN (SELECT number FROM #TAB) AND id NOT IN (SELECT id FROM #IDToKEEP)
My table (named Inventory) is the following:
InventoryType,LocationID,InventoryLevel,SafetyStock,MaxLevel,ModifiedAt
Erasors,1,14,3,15,11-2014
Erasors,2,4,10,50,10-2014
Erasors,2,5,10,50,11-2014
Pencils,1,10,5,45,11-2014
Pencils,2,23,15,50,11-2014
Pens,1,9,10,50,11-2014
Pens,2,55,10,50,12-2014
There are three primary keys: InventoryType, LocationID, and ModifiedAt.
Given a specified LocationID, I'd like the query to return all for each distinct InventoryType where the date for each tuple returned is the most recent ModifiedAt date among records for that given inventory type with the specified LocationID. Eg, LocationID = 2 would return:
InventoryType,LocationID,InventoryLevel,SafetyStock,MaxLevel,ModifiedAt
Erasors,2,5,10,50,11-2014
Pencils,2,23,15,50,11-2014
Pens,2,55,10,50,12-2014
My attempt thus far is the following:
SELECT InventoryType, LocationID, InventoryLevel,
SafetyStock, MaxLevel, ModifiedAt
FROM Inventory
WHERE LocationID = 2 AND ModifiedAt IN
(SELECT TOP 1 ModifiedAt
FROM Inventory
WHERE LocationID = 2
ORDER BY ModifiedAt DESC);
My query returns:
InventoryType,LocationID,InventoryLevel,SafetyStock,MaxLevel,ModifiedAt
Pens,2,55,10,50,12-2014
Any help would be appreciated.
You need a correlated subquery. Try this instead:
SELECT InventoryType, LocationID, InventoryLevel, SafetyStock, MaxLevel, ModifiedAt
FROM Inventory as i
WHERE LocationID = 2 AND
ModifiedAt IN (SELECT TOP 1 i2.ModifiedAt
FROM Inventory as i2
WHERE i2.LocationID = 2 AND i2.InventoryType = i.InventoryType
ORDER BY i2.ModifiedAt DESC
);
Use SELECT DISTINCT for selecting distinct InventoryType.
SELECT DISTINCT InventoryType, LocationID,
InventoryLevel, SafetyStock, MaxLevel, ModifiedAt
FROM Inventory
WHERE LocationID = 2
AND ModifiedAt IN
(SELECT TOP 1 ModifiedAt FROM Inventory WHERE LocationID = 2 ORDER BY ModifiedAt DESC)
I have a table [applicants] with the following fields:
1) MemberID
2) Attempts
Some of my attempts are NULL.
I would like to update the attempts field to 0 for those rows where the MemberID count in the table is 1.
Any help is appreciated.
general approach would be
update applicants set
Attempts = 0
where
MemberID in (select t.MemberID from applicants as t group by t.MemberID having count(*) = 1) and
Attempts is null -- if you need it
in sql server you can do something like:
with cte as (
select *, count(*) over(partition by MemberID) as cnt
from applicants
)
update cte set
Attempts = 0
where cnt = 1 and Attempts is null
UPDATE applicants
SET Attempts = 0
WHERE MemberID IN
(SELECT MemberID FROM applicants GROUP BY MemberID HAVING COUNT(MemberID)=1)
AND Attempts IS NULL
this is my table structure,
create table ArticleTbl
(
ArticleID bigint identity(1,1),
ProductID int ,
ArticleName varchar(100),
PubDate datetime,
AuthorName varchar(50),
AuthorImage bit,
HtmlValues nvarchar(max)
)
here productid are
1=creditcard,2=prepaidcard,3 saving account,.........
each productid is having multiple rows of records ,
i want to select latest 2 records of each productid in one shot instead of going to database each time .
my procedure now is like..
create proc USP_GetArticle_ByProduct(#ProductID int) as
select top(2) * from ArticleTbl where ProductID=#ProductID
if i use this procedure each productid i have to go to database...
how to get one shot all product(latest 2 records ) using query????
SELECT
*
FROM
(
SELECT
/*Random order per product*/
ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY NEWID() ) AS Ranking,
*
FROM
ArticleTbl
) foo
WHERE
foo.Ranking <= 2
i figure this is on sql server yeah?
if so, you could do this...
select a1.*
from Articletbl a1
where a1.articleid in
(select top 2 a2.articleid
from ArticleTbl a2
where a2.productid = a1.productid
order by a2.articleid DESC)
order by a1.ProductID