Trying to retrieve records with data in one column that doesn't match data from another column - ms-access

So I have a table of records in Access (example below), where I want to retrieve the records where an Entry Date occurs on a date that a Transaction Date that does not occur for a given person. There also may days that a transaction may occur, but there is no Entry Date. I am only concerned here with the rows that have an Entry Date/Time.
Transaction Date/Time First Name Last Name Entry Date/Time
07/02/2014 11:45 PM Sally Smith 07/14/2014 12:17 PM
07/02/2014 07:34 AM John Foobar 07/02/2014 01:34 PM
07/03/2014 08:56 AM Sally Smith 07/02/2014 08:00 AM
07/03/2015 09:33 AM John Foobar
What I would be interested in retrieving here is the first transaction for Sally Smith, because its Entry Date occurs on a day that Sally Smith had no Transactions.
I am trying to build this utilizing a Query where the data is retrieved from SQL.
Thanks!

You could use a sub query that checks whether there's no record having an entry date that matches a transaction date.
Use the Format function to check on the date part only.
PS I'd include a PersonID primary key as the combination of first and last name is not unique.
Originally, in the sub query FORMAT(b.[Entry Date/Time],'dd-mm-yyyy') and Format(a.[Transaction Date/Time],'dd-mm-yyyy') were used.
I made an error while copy and pasting.
Entry Date should refer to table alias a and Transaction Date should refer to table alias b.
I adjusted the original query.
SELECT a.[Transaction Date/Time], a.[First Name], a.[Last Name], a.[Entry Date/Time]
FROM yourtable a
WHERE a.[Entry Date/Time] IS NOT NULL
AND NOT EXISTS
(
SELECT '1'
FROM yourtable AS b
WHERE FORMAT(a.[Entry Date/Time],'dd-mm-yyyy') = Format(b.[Transaction Date/Time],'dd-mm-yyyy')
AND b.[First Name] = a.[First Name]
AND b.[Last Name] = a.[Last Name]
)

Related

Previous record in mysql with duplicated records and random ID

My applicants table has multiple records with the same date and an index with missing and non-sequential values, much like this:
ID date Name
3422 2021-02-08 Priscilla
3421 2021-02-04 Rahul
3437 2021-02-04 Ella
3435 2021-02-04 Aarushi
3436 2020-02-03 Colin
I need to get the previous record to the current one in database order by date. So if the current record is Ella's I need to return Rahul's and then Priscilla's.
I've dealt with the next equivalent by using an IN statement to exclude IDs in multiple dates:
SELECT *
FROM applicants
WHERE date_created <= $mdata['currdate']
AND applicant_id NOT IN ( . $mdata['currids'] . )
ORDER
BY date_created DESC
LIMIT 1
But this doesn't work with previous calls.
I've seen several previous answers but none quite fit my situation and I'm not versed enough in SQL to modify them to my needs. Some pointers towards to a solution will be very welcome.

mysql highly selective query

I have a data set like this:
User Date Status
Eric 1/1/2015 4
Eric 2/1/2015 2
Eric 3/1/2015 4
Mike 1/1/2015 4
Mike 2/1/2015 4
Mike 3/1/2015 2
I'm trying to write a query in which I will retrieve users whose MOST RECENT transaction status is a 4. If it's not a 4 I don't want to see that user in the results. This dataset could have 2 potential results, one for Eric and one for Mike. However, Mike's most recent transaction was not a 4, therefore:
The return result would be:
User Date Status
Eric 3/1/2015 4
As this record is the only record for Eric that has a 4 as his latest transaction date.
Here's what I've tried so far:
SELECT
user, MAX(date) as dates, status
FROM
orders
GROUP BY
status,
user
This would get me to a unqiue record for every user for every status type. This would be a subquery, and the parent query would look like:
SELECT
user, dates, status
WHERE
status = 4
GROUP BY
user
However, this is clearly flawed as I don't want status = 4 records IF their most recent record is not a 4. I only want status = 4 when the latest date is a 4. Any thoughts?
SELECT user, date
, actualOrders.status
FROM (
SELECT user, MAX(date) as date
FROM orders
GROUP BY user) AS lastOrderDates
INNER JOIN orders AS actualOrders USING (user, date)
WHERE actualOrders.status = 4
;
-- Since USING is being used, there is not a need to specify source of the
-- user and date fields in the SELECT clause; however, if an ON clause was
-- used instead, either table could be used as the source of those fields.
Also, you may want to rethink the field names used if it is not too late and user and date are both found here.
SELECT user, date, status FROM
(
SELECT user, MAX(date) as date, status FROM orders GROUP BY user
)
WHERE status = 4
The easiest way is to include your order table a second time in a subquery in your from clause in order to retrieve the last date for each user. Then you can add a where clause to match the most recent date per user, and finally filter on the status.
select orders.*
from orders,
(
select ord_user, max(ord_date) ord_date
from orders
group by ord_user
) latestdate
where orders.ord_status = 4
and orders.ord_user = latestdate.ord_user
and orders.ord_date = latestdate.ord_date
Another option is to use the over partition clause:
Oracle SQL query: Retrieve latest values per group based on time
Regards,

Display a table with just the second duplicate rows removed yet keep the first row

So, I have a table with 3 columns, of which the first column consists of IDs and the last column consists of dates. What I need is, to sort the table by dates, and remove any duplicate IDs with a later date (and keep the ID with the earliest date).
For example,
This is how my table originally looks like -
123 Ryan 01/01/2011
345 Carl 03/01/2011
123 Lisa 01/02/2012
870 Tiya 06/03/2012
345 Carl 07/01/2012
I want my resultant table to look like this -
123 Ryan 01/01/2011
345 Carl 03/01/2011
870 Tiya 06/03/2012
I'm using VBA Access Code to find a solution for the above, and used SQL Queries too, however my resultant table either has no duplicates whatsoever or displays all the records.
Any help will be appreciated.
This will create a new table:
SELECT tbl.SName, a.ID, a.BDate
INTO NoDups
FROM tbl
INNER JOIN (
SELECT ID, Min(ADate) As BDate
FROM tbl GROUP BY ID) AS a
ON (tbl.ADate = a.BDate) AND (tbl.ID = a.ID);

How can I find the correct prior status row in this table with a SQL query?

Imagine a workflow for data entry. Some forms come in, they are typed into a system, reviewed, and hopefully approved. However, they can be rejected by a manager and will have to be entered again.
So, an ideal workflow would go like this:
recieved > entered > approved
But this COULD happen:
received > entered > rejected > entered > rejected > approved
At each stage, we record who updated the form to its current status - who entered it, who rejected it, or who approved it. So the forms status table looks like this:
form_id status updated_by updated_at
1 received Bob (timestamp)
1 entered Bob (timestamp)
1 approved Susan (timestamp)
2 received Bob (timestamp)
2 entered Bob (timestamp)
2 rejected Susan (timestamp)
2 entered Carla (timestamp)
2 rejected Susan (timestamp)
2 entered Sam (timestamp)
2 approved Susan (timestamp)
Here's what I'm trying to do: write a rejection report. I want a row for each rejection, and joined to that row, I want to see who did the work that got rejected.
As a human, I can see that, for a given status row with status 'rejected', the row that will tell me who did the faulty work will be the one that
shares the same form_id and
has a prior timestamp closest to the rejection.
But I'm having trouble telling MySQL that.
Can anybody see how to construct this query?
A subselect ended up working for me.
SELECT
`s1`.`form_id`,
(
SELECT
`s2`.`updated_by`
FROM
statuses s2
WHERE
`s2`.`form_id` = `s1`.`form_id`
AND
`s2`.`updated_at` < `s1`.`updated_at`
ORDER BY
`s2`.`updated_at` DESC
LIMIT 1
) AS 'made_rejected_change'
FROM
statuses s1
WHERE
`s1`.`status` = 'rejected'
Another solution that uses subselect (this time not a correlated subquery):
SELECT
w1.*,
w2.entered_by
FROM (
SELECT
wr.form_id,
wr.updated_at AS rejected_at,
wr.updated_by AS rejected_by,
MAX(we.updated_at) AS entered at
FROM workflow wr
INNER JOIN workflow we ON we.status = 'entered'
AND wr.form_id = we.form_id
AND wr.updated_at > we.updated_at
WHERE wr.status = 'rejected'
GROUP BY
wr.form_id,
wr.updated_at,
wr.updated_by
) w1
INNER JOIN workflow w2 ON w1.form_id = w2.form_id
AND w1.entered_at = w2.updated_at
The subselect lists all the rejecters and the immediately preceding entered timestamps. Then the table is joined once again to extract the names corresponding to the entered_at timestamps.
You want to get the rejected timestamp and then figure out the entry that appeared right before it based on the timestamp. I'm assuming that timestamp actually holds a date/time and isn't an SQL server timestamp field (completely different).
declare #rejectedTimestamp timestamp
select #rejectedTimestamp = timestamp
from table
where status = 'rejected'
select top 1 *
from table
where timestamp < #rejectedtimestamp
order by timestamp desc

Compare date fields in SQL server

I've a flat file that I cleaned the data out using SSIS, the output looks like that :
MEDICAL ADMIT PATIENT PATIENT DATE OF DX
REC NO DATE NUMBER NAME DISCHARGE Code DRG #
123613 02/16/09 12413209 MORIBALDI ,GEMMA 02/19/09 428.20 988
130897 01/23/09 12407193 TINLEY ,PATRICIA 01/23/09 535.10 392
139367 02/27/09 36262509 THARPE ,GLORIA 03/05/09 562.10 392
141954 02/25/09 72779499 SHUMATE ,VALERIA 02/25/09 112.84 370
141954 03/07/09 36271732 SHUMATE ,VALERIA 03/10/09 493.92 203
145299 01/21/09 12406294 BAUGH ,MARIA 01/21/09 366.17 117
and the report (final results) attached in the screen shot from the final excel report.
so what's happening is IF the same name or same account number is duplicate, that means the patient has entered the hospital again and needs to be included in the report.
![alt text][1]
what I need to do is...
Eliminate any rows that is NOT duplicate (not everybody in this file has been admitted again)
and compare the dates to get the ReAdmitdate and ReDischargedate
I dumped the data into a SQL table and trying to compare the dates to figure out "ReAdmitdate" and "ReDischargedate"
any help is appreciated.
Is there a unique identifier for the patients? I'm assuming patient_number is the unique identifier for each patient, and medical_rec_no is incremental.
This query works by joining the patient records to records from the same patient that have a later admit date.
SELECT p1.patient_number, p1.admit_date,
p2.admit_date as readmit_date, p2.discharge_date AS redischarge_date
FROM patient p1
INNER JOIN patient p2
ON p1.patient_number = p2.patient_number AND
p2.medical_rec_no <> p1.medical_rec_no
LEFT OUTER JOIN patient p3
ON p3.patient_number = p1.patient_number AND
p3.medical_rec_no <> p1.medical_rec_no AND
p3.admit_date < p2.admit_date
WHERE p3.patient_number IS NULL
ORDER BY p1.patient_number, p1.admit_date, p1.medical_rec_no
I used to work for a hospital on the Data Warehousing team (building cubes used by the whole organization) and we had visit numbers to go by and from there we could determine if it was an appointment set (or re-admission as you refer to it). Do you have any appointment numbers and visit numbers, it may be useful to add those to your SQL table.