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' )
Related
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.
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
I see some questions relating to mine, but they are not exactly the same.
I need to make a SELECT in a DB2 database where I keep only distinct IDs with their data.
Example, I have some datas :
ID DATE_BEGIN DATE_END
1111 2014-01-01 2016-01-02
1111 2018-01-05 2018-01-03
1111 1990-01-01 9999-12-31
2222 1998-02-02 2000-12-20
In my case, I want to keep :
1111 1990-01-01 9999-12-31
2222 1998-02-02 2000-12-20
My SELECT statement:
SELECT
ID, DATE_BEGIN, DATE_END
FROM TABLE_NAME T1
WHERE DATE_END = (SELECT
MAX(DATE_END)
FROM TABLE_NAME T2
WHERE T2.DATE_END = T1.DATE_END)
But I keep getting every records.
Thanks for the help !
I asked a similar question previously, please refer to my post here: Get the latest date for each record
SELECT ID, DATE_BEGIN, DATE_END
FROM (
SELECT ID, DATE_BEGIN, DATE_END
,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [DATE_END] DESC) RN
FROM TABLE_NAME
)A
WHERE A.RN = 1
Credit goes to the original answer in my post.
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)
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.