How can i remove duplicate rows with in my sql server database - sql-server

I have this table of attendance system with columns dateinout, checkin, checkout etc. user punch in when come to office and punch out when go out. system retrieve data two time from fingerprint scanner machine. I want to delete rows with more than one count in same date where punch in is between 7am to 11 am also the rows with check out with same date in between 11 am to 6 pm.
SELECT
a.Logid,
a.Userid,
a.CheckTime,
a.Name
FROM Checkinout a
JOIN
(SELECT
userid,
name,
dateinout,
Intime,
Outtime
FROM att
WHERE Intime BETWEEN '07:00:00.0000000' AND '11:00:00.0000000'
AND userid= 37
GROUP BY userid, dateinout, Intime, Outtime, name
HAVING COUNT(Intime)>1) b
ON a.Userid= b.userid
ORDER BY CheckTime ASC;

You can use cte to delete duplicates from the att table based on your grouping criteria.
;WITH CTE AS(
SELECT
row_number() over (partition by userid,dateinout, Intime, Outtime order by date) AS ROWNUMBER,
userid,
dateinout,
Intime,
Outtime
FROM
att
WHERE
Intime BETWEEN '07:00:00.0000000' AND '11:00:00.0000000'
AND userid = 37
)
DELETE FROM CTE WHERE ROWNUMBER>1

You can do step by step.
Firstly, find insert count in time range:
SELECT COUNT(Logid), userid
FROM Checkinout
WHERE Intime BETWEEN '07:00:00.0000000' AND '11:00:00.0000000'
GROUP BY Logid
HAVING COUNT(Logid) > 1
after, you got list, you can distract by property how you need

Related

using Row_number() and Partition, then ordering desc, and selecting top result in DB2

i have a db2 linked server i'm running a query on through SQL Server.
select *
from openquery (DO,'
select distinct HOUSE_NUM, NAME, DOB, AGE, row_number()
over(partition by DOB) rownum
from schema.INFO
where HOUSE_NUM = ''332''
group by HOUSE_NUM, NAME, DOB, AGE
order by NAME, rownum desc
limit 1
with ur');
the table has historical records, so there is a row for each age of the individual. i want to select the highest numbered row for each partition because that will give me their current age, however when i put limit 1 to select the top result i only get 1 row which ignores all the other people. the problem is there are multiple people living in a house and i need all of their ages, not just one of them. how do i select the top result of each partition in db2?
Before applying limit
After applying limit, i need the other names too
A Db2 query would look like this - rownumber cannot be referred to in the same query part this is why I used a CTE
with temp as (
select distinct HOUSE_NUM, NAME, DOB, AGE
, row_number() over(partition by HOUSE_NUM, NAME, DOB order by age desc) as rownum
from schema.INFO
where HOUSE_NUM = '332'
)
select *
from temp
where rownum = 1
Hope this helps - due to the limited information about the data it is only a best guess

Get latest row and sum of a column in it togather

In my table I have three columns amount,date,memberID. Now I want to get Latest amount inserted in to the table and the sum of whole amount inserted so far.
My Query was like this
SELECT amount , SUM(amount) as TotalAmount FROM [Transactions]
WHERE memberid = 1629 Order By Date DESC
But this throws an error like this
Msg 8120, Level 16, State 1, Line 1
Column 'Transactions.amount' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can anyone point out what I am doing wrong here?
SELECT amount AS LatestAmount,
(SELECT SUM(amount) FROM [Transactions]) AS TotalAmount
FROM [Transactions]
WHERE date = (SELECT MAX(date) FROM [Transactions])
Note that in the event of a tie for more than one latest amount, the above query would produce one record for each tying transaction. If you want only one result, and you are using SQL Server 2008 or later, you can use TOP(1) to limit to a single result:
SELECT TOP(1) amount AS LatestAmount,
(SELECT SUM(amount) FROM [Transactions]) AS TotalAmount
FROM [Transactions]
WHERE date = (SELECT MAX(date) FROM [Transactions])
Just Add Group by clause
SELECT amount , SUM(amount) as TotalAmount FROM [Transactions]
GROUP BY amount WHERE memberid = 1629 Order By Date DESC

SQL Server - Distinct case in one column but last record in second column

I have a requirement (simple, but can't find simple solution) to fetch mobile number and unique transaction id (latest transaction would be good, but any transaction id is also ok)
Sample Data
Seq. Mobile No. Transaction No.
1 1234567890 ABC1234
2 2345678901 ABC2392
3 2345678901 ABC2782
I simply want to find mobile number 2345678901 and any of the one transaction, however latest would be good.
Output
Seq. Mobile No. Transaction No.
1 1234567890 ABC1234
2 2345678901 ABC2782
I know simply DISTINCT won't work, so not sure what's the best way to get the outcome.
I found a way to do it via sub-query, but I want to do it in single query for better performance.
Plz Help!!
You can use ROW_NUMBER for this:
SELECT Seq, MobileNo, TransactionNo
FROM (
SELECT Seq, MobileNo, TransactionNo,
ROW_NUMBER() OVER (PARTITION BY MobileNo ORDER BY Seq DESC) AS rn
FROM mytable) AS t
WHERE t.rn = 1
The above query will pick exactly one record per MobileNo: the one having the greatest Seq value.
You can use group by.
select [Seq], [Mobile No], [Transaction No] from yourtable t1
inner join
(select [Mobile No], max([Transaction No]) as T_no from yourtable
group by [Mobile No]) t2
on t1.[Mobile No]=t2.[Mobile No] and t1.[Transaction No]=t2.T_no
Right query gives you latest [Transaction No] per [Mobile No] and left query is used only for finding matching [Seq].
CREATE TABLE #Transaction
(
Seq VARCHAR(12),
MobileNo VARCHAR(12),
TransactionNo VARCHAR(12)
)
INSERT INTO #Transaction VALUES
(1,'1234567890','ABC1234')
,(2,'2345678901','ABC2392')
,(3,'2345678901','ABC2782')
SELECT DT.Seq,DT.MobileNo,DT.TransactionNo FROM
(SELECT Seq,
MobileNo,
TransactionNo,
ROW_NUMBER() OVER(PARTITION BY MobileNo ORDER BY Seq) AS Rn
FROM
#Transaction) DT
WHERE DT.Rn = 1

SELECT records that were not yesterday

I have the following CTE
;
WITH cte
AS
(
select t.UserId, t.Date
from (select
Date
, UserId
, row_number() over(partition by UserId order by Date desc) as RowNumber
from dbo.Income_Expenses) as t
where t.RowNumber = 1
)
If I make a selection on it, I'll get the following results:
Date UserId RowNumber
2015-05-10 00:00:00.000 6 1
2015-05-08 00:00:00.000 7 1
Basically I get the last record that has been inserted by every user.
Now, when I make a selection on the CTE, I want to get the records that are older than the day before yesterday.
I.E. Today is May 10th; I want all the records that are from May 8th and later. (8th, 7th, etc, but not 9th and 10th).
So I tried some expression with DATEADD, DATEDIFF and none of them worked.
Can someone help me?
Try to add this condition to the cte: and datediff(day, date, getDate()) >= 2

SQL Server how to fetch single record from multiple resultset per condition

I have a table A which has multiple records per year. I would like to pick the latest record for the current year. If there is not record for current year, I would like to pick the record which has the latest value for the year field. Can someone help?
I have the below query in SQL Server 2008 V2.
DECLARE #CurrentYear INT
SET #CurrentYear = YEAR(GETDATE())
SELECT Account,
COLUMN2,
COLUMN3,
YEAR_c
FROM A WHERE YEAR_c = #CurrentYear
If there are multiple records in table A for current year 2017, this query will return all records. I would like select the latest record from this list. Also, I need to select one record for the combination of Account & Year_c.
This query would return latest record per account:
DECLARE #CurrentYear INT
SET #CurrentYear = YEAR(GETDATE())
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY Account ORDER BY YEAR_c DESC) AS RN,
Account,
COLUMN2,
COLUMN3,
YEAR_c
FROM A WHERE YEAR_c <= #CurrentYear
) AS Results
WHERE RN = 1
The trick is to select all records and assign them row-index per each account (partition), sorted by year descending.
Then select only ones with row-index of 1 which are the latest per account.
Hope this helps.
You simply need an TOP and ORDER BY though this is usually done on a DATETIME column. Not just a YEAR column.
SELECT TOP 1
Account,
COLUMN2,
COLUMN3,
YEAR_c
FROM A
ORDER BY
YEAR_c DESC
,Account
The Account in the ORDER BY is just a suggestion... since only ordering by the year could return different results each time
Or, one for each group...
SELECT DISTINCT
Account,
COLUMN2,
COLUMN3,
max(YEAR_c)
FROM A
GROUP BY
Account
COLUMN2,
COLUMN3,

Resources