Delete duplicate rows in Access SQL-Query - sql

i want to create an Access SQL Query for deleting duplicate rows.
My Table:
CustID EventDate EventID
12 01.01.2019 1001
10 02.01.2019 1002
11 03.01.2019 1003
10 01.01.2019 1001
11 03.01.2019 1004
The table has no primary key.
I want to delete every duplicate CustID.
The result should have every CustID once with
Prio 1. the most recent EventDate
Prio 2. the biggest EventID
The result would look like this:
CustID EventDate EventID
12 01.01.2019 1001
10 02.01.2019 1002
11 03.01.2019 1004
I don't want to use macros.
How would the sql statement look like in access?
Thank you in advance.

Assuming most recent date and biggest event ID will always be in the same record, consider:
Query1:
SELECT Table1.CustID, Max([EventDate] & [eventID]) AS ID
FROM Table1
GROUP BY Table1.CustID;
Query2:
DELETE FROM Table1 WHERE Not CustID & EventDate & EventID IN (SELECT CustID & ID
FROM Query1);

You can apply the conditions for deletion with EXISTS:
DELETE FROM tablename AS t
WHERE EXISTS (
SELECT 1 FROM tablename
WHERE
CustID = t.CustID
AND
(EventDate > t.EventDate OR (EventDate = t.EventDate AND EventID > t.EventID))
)

This will help you :
Select distinct * into ‪#‎tmpl‬ From MY_TABLE
Delete from MY_TABLE
Insert into MY_TABLE
Select * from #tmpl
Drop table #tmpl
While creating temp tables if throw errors, then create another real table and perform the same.

Related

SQL: Take maximum value, but if a field is missing for a particular ID, ignore all values

This is somewhat difficult to explain...(this is using SQL Assistant for Teradata, which I'm not overly familiar with).
ID creation_date completion_date Difference
123 5/9/2016 5/16/2016 7
123 5/14/2016 5/16/2016 2
456 4/26/2016 4/30/2016 4
456 (null) 4/30/2016 (null)
789 3/25/2016 3/31/2016 6
789 3/1/2016 3/31/2016 30
An ID may have more than one creation_date, but it will always have the same completion_date. If the creation_date is populated for all records for an ID, I want to return the record with the most recent creation_date. However, if ANY creation_date for a given ID is missing, I want to ignore all records associated with this ID.
Given the data above, I would want to return:
ID creation_date completion_date Difference
123 5/14/2016 5/16/2016 2
789 3/25/2016 3/31/2016 6
No records are returned for 456 because the second record has a missing creation_date. The record with the most recent creation_date is returned for 123 and 789.
Any help would be greatly appreciated. Thanks!
Depending on your database, here's one option using row_number to get the max date per group. You can then filter those results with not exists to check against null values:
select *
from (
select *,
row_number() over (partition by id order by creation_date desc) rn
from yourtable
) t
where rn = 1 and not exists (
select 1
from yourtable t2
where t2.creationdate is null and t.id = t2.id
)
row_number is a window function that is supported in many databases. mysql doesn't but you can achieve the same result using user-defined variables.
Here is a more generic version using conditional aggregation:
select t.*
from yourtable t
join (select id, max(creation_date) max_creation_date
from yourtable
group by id
having count(case when creation_date is null then 1 end) = 0
) t2 on t.id = t2.id and t.creation_date = t2.max_creation_date
SQL Fiddle Demo

SQL Access -- Keep record only with most recent timestamp

I have a table that appears as follows:
Time Name Cust_ID Num_Calls Num_Orders
12.00 ABC 100 20 10
12.25 PQR 102 23 12
12.30 ABC 100 26 15
01.00 ABC 100 26 18
02.00 PQR 102 23 14
04.00 PQR 102 25 20
How do I delete the earlier records for each "Name & Cust_ID" and keep the most recent one. The other fields in the record may change as I run them through my Access Database, but Name and ID remains the same.
My output at the End of the Day should be:
Time Name Cust_ID Num_Calls Num_Orders
01.00 ABC 100 26 18
04.00 PQR 102 25 20
I think if your cust_id is unique, you should make it a primary key in the table.
Then whenever you have a new entry, first check and see if the current cust_id already exists.
If yes, update that entry in the table.
Else do an insert.
Try this...
This should give you your most recent records based on max(time), you could delete the complement of this set.
SELECT * FROM YOUR_TABLE A
INNER JOIN
( SELECT MAX(time) MAX_time
, NAME , CUST_ID
FROM YOUR_TABLE
GROUP BY
NAME , CUST_ID )B
ON A.NAME=B.Name
and A.CUST_ID=B.CUst_ID
and A.time =B.max_time
So you would delete the following records
DELETE FROM YOUR_TABLE
WHERE EXISTS
(SELECT * FROM YOUR_TABLE B
WHERE TIME <>( SELECT MAX(time) FROM YOUR_TABLE C WHERE B.NAME=C.Name
and C.CUST_ID=B.CUst_ID )
AND A.NAME=B.Name
and A.CUST_ID=B.CUst_ID)

Select info from table where row has max date

My table looks something like this:
group date cash checks
1 1/1/2013 0 0
2 1/1/2013 0 800
1 1/3/2013 0 700
3 1/1/2013 0 600
1 1/2/2013 0 400
3 1/5/2013 0 200
-- Do not need cash just demonstrating that table has more information in it
I want to get the each unique group where date is max and checks is greater than 0. So the return would look something like:
group date checks
2 1/1/2013 800
1 1/3/2013 700
3 1/5/2013 200
attempted code:
SELECT group,MAX(date),checks
FROM table
WHERE checks>0
GROUP BY group
ORDER BY group DESC
problem with that though is it gives me all the dates and checks rather than just the max date row.
using ms sql server 2005
SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group
That works to get the max date..join it back to your data to get the other columns:
Select group,max_date,checks
from table t
inner join
(SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group)a
on a.group = t.group and a.max_date = date
Inner join functions as the filter to get the max record only.
FYI, your column names are horrid, don't use reserved words for columns (group, date, table).
You can use a window MAX() like this:
SELECT
*,
max_date = MAX(date) OVER (PARTITION BY group)
FROM table
to get max dates per group alongside other data:
group date cash checks max_date
----- -------- ---- ------ --------
1 1/1/2013 0 0 1/3/2013
2 1/1/2013 0 800 1/1/2013
1 1/3/2013 0 700 1/3/2013
3 1/1/2013 0 600 1/5/2013
1 1/2/2013 0 400 1/3/2013
3 1/5/2013 0 200 1/5/2013
Using the above output as a derived table, you can then get only rows where date matches max_date:
SELECT
group,
date,
checks
FROM (
SELECT
*,
max_date = MAX(date) OVER (PARTITION BY group)
FROM table
) AS s
WHERE date = max_date
;
to get the desired result.
Basically, this is similar to #Twelfth's suggestion but avoids a join and may thus be more efficient.
You can try the method at SQL Fiddle.
Using an in can have a performance impact. Joining two subqueries will not have the same performance impact and can be accomplished like this:
SELECT *
FROM (SELECT msisdn
,callid
,Change_color
,play_file_name
,date_played
FROM insert_log
WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
ORDER BY callid ASC) t1
JOIN (SELECT MAX(date_played) AS date_played
FROM insert_log GROUP BY callid) t2
ON t1.date_played = t2.date_played
SELECT distinct
group,
max_date = MAX(date) OVER (PARTITION BY group), checks
FROM table
Should work.

T-SQL Select accounts with no activity

I have this table
ID InvoiceNo Created_date
-- --------- ------------
1 123 1/1/2009
1 234 1/1/2010
1 2304 2/1/2010
1 av245 3/1/2011
1 45wd3 4/1/2011
2 345 1/1/2010
2 4w5 2/1/2010
I am trying to select the ID where there has been no activity since 11/1/2010.
so my results should only show ID 2.
I used EXISTS, NOT EXIST but it still shows ID 1. Any help is appreciated.
Not optimized for performance, but I would just do something like this:
quick and dirty alert
select distinct q.id from (select id, max(created_date) as latestdate from TABLENAME group by id) q where q.latestdate <= '2010-11-01'
in oracle i might write something like this:
select id from mytable
MINUS
SELECT id from mytable where created_dt > '2010-11-01'
to use NOT IN:
select * from mytable
where id not in ( select id from mytable where created_dt > '2010-11-01' )

Find out the Old Date from a date column in sql

How the find the oldest values from the datetime column?
I have table with datetime column (UpdateDate), and i need to find out the oldest data based on the UpdateDate .
Id UpdateDate Desc
-----------------------------------------
1 2010-06-15 00:00:00.000 aaaaa
2 2009-03-22 00:00:00.000 bbbbb
3 2008-01-12 00:00:00.000 ccccc
4 2008-02-12 00:00:00.000 ddddd
5 2009-04-03 00:00:00.000 eeeee
6 2010-06-12 00:00:00.000 fffff
I have Find out the old year dates from the current date using
Select UpdateDate from Table1 where DATEDIFF(YEAR,UpdateDate,getdate()) > 0 Query. But I need to find out the 2008th data only (Since the 2008 is the oldest one here)
I dont know what is there in the Table I need find out the Oldest date values.. How is it Possible?
Select UpdateDate from Table1 where DATEDIFF(YEAR,PartDateCol,getdate()) IN
(Select MAX(DATEDIFF(YEAR,PartDateCol,GETDATE())) DiffYear from Table1)
This will return two record of 2008. If your records has four 2006 date than it return all 2006 data if difference is large.
One way of doing this is
Select UpdateDate from Table1 where YEAR(UpdateDate )=2008
But, you can find out the oldest dates by ordering the data as such
Select * from Table1 order by UpdateDate ASC
You can use top and order by.
select top(1) UpdateDate
from Table1
order by UpdateDate
Update:
If you want all rows for the first year present you can use this instead.
select *
from (
select *,
rank() over(order by year(UpdateDate)) as rn
from Table1
) as T
where T.rn = 1
If you want the data that within 2008 year try this:
Select UpdateDate From Table1
Where Year(UpdateDate) =
(
Select Year(UpdateDate)
from Table1 Order By UpdateDate ASC Limit 1
) ;