Reuse logic to query data based on date filter - sql

I have logic in place to pull records based on date. For example i have to check if a record that appeared in a week has also occurred in next 14 days then that records need to be flagged. So basically i have put self join to get that record.
Now i have to pull record for 3 months and see if that record appeared again but logic will be same(in next 14 days), so ideally i have to change date filter in query for every week and get data, is there a way i can do it in same query and get full 3 months data
let me know if more clarification required.

Related

SQL- Return less than 24 hour or 1 day difference between 2 dates values using self join

Logic: If an admission date is not reported on all claims, combine claims for the same beneficiary and provider that have less than a one-day break between the end date of the first claim and the start date of the next claim. For example, if the end date of the first claim is December 18 and the start date of the next claim is December 19, then combine the claims as a single stay. However, if the second claim has a start date of December 20 or later, then do not combine the claims.
I am working with MS SQL server and since it want to combine claims for less than one day break, I prefer to delete all but one record with the same beneficiaries.
The database is denormalized with one table and 52 fields so I prefer not to left or right join because it would double record. I watched this Youtube video https://www.youtube.com/watch?v=Ip6Ty2qmQXg and it shows how to self-join without doubling the records.
Given that, this is what I have came up so far. Since the question said to combine claims I want to delete the "duplicate" records but I do not know how to delete after self join. See the code below
-- self join
SELECT *
FROM #Metric2InpatientNoDischargeNoAdmission BEN1, #Metric2InpatientNoDischargeNoAdmission BEN2
WHERE BEN1.BEN_ID = BEN2.BEN_ID
AND BEN1.PERF_PROV_KEY = BEN2.PERF_PROV_KEY
AND BEN1.DTE_FIRST_SVC < BEN2.DTE_FIRST_SVC
AND DATEDIFF(day, BEN1.DTE_LAST_SVC, BEN2.DTE_FIRST_SVC) > 1 )
Edit:
I ran the above code and it returned more rows than the original table so this code is obviously not right. Help!!! :(

Running an Access query on a FILTERED table

I have some related tables that I want to run a Totals/Group By query on.
My "Tickets" table has a field called "PickDate" which is the date that the order/ticket was fulfilled.
I want to group by the weekday (name) (a calculated field) so that results for certain customers on the same day of the week are grouped. Then the average ticket completion time can be calculated per customer for each weekday. It would look something like the following.
--CustName---Day---AvTime
Customer 1 - MON - 72.3
- TUE - 84.2
- WED - 110.66
..etc
..etc
..etc
Customer 2 ..
This works fine but the problem I am having is that when this query is run, it works on every record from the tickets table. There are some reasons that, for certain reports, the data that it the query is referencing should be restricted between a date range; for example to track a change in duration over a number of weeks.
In the query properties, there is a property, "filter", to which I can add a string such as:
"([qryCustomerDetails].[PickDate] Between #11/1/2021# And #11/14/2021#)"
to filter the results. The only issue is that since each date is unique, the "group by" of like days such as "Monday" is overridden by this unique date "11/1/2021". The query only works when the PickDate is removed as a field. However, then I can't access it to filter by it.
What I want to achieve would be the same as; in the "Tickets" table itself filtering the results between two dates and then having a query that could run on that filtered table.
Is there any way that I could achieve this?
For reference here is the SQL of the query.
FROM tblCustomers INNER JOIN tblTickets ON tblCustomers.CustomerID = tblTickets.CustomerID
GROUP BY tblCustomers.Customer, WeekdayName(Weekday([PickDate]),False,1), tblCustomers.Round, Weekday([PickDate])
ORDER BY tblCustomers.Round, Weekday([PickDate]);
You probably encountered two issues. The first issue is that to filter results in a totals query by un totaled fields you use HAVING rather than WHERE. the second issue is that calculated fields like Day don't exist at the time of the query. You can't say having Day > Mon. Instead you must repeat the calculation of Day: Having CalculateDay(PickDate) > Monday
The designer will usually figure out whether you want having or where automatically. So here is my example:
this gives you the SQL:
SELECT Tickets.Customer, WeekdayName(Weekday([PickDate])) AS [Day], Avg(Tickets.Time) AS AvTime
FROM Tickets
GROUP BY Tickets.Customer, WeekdayName(Weekday([PickDate])), Tickets.PickDate
HAVING (((Tickets.PickDate) Between #11/16/2021# And #11/17/2021#))
ORDER BY Tickets.PickDate;

Need column comprised of data from date two weeks ago for comparison

Let me start by saying that I am somewhat new to SQL/Snowflake and have been putting together queries for roughly 2 months. Some of my query language may not be ideal and I fully understand if there's a better, more efficient way to execute this query. Any and all input is appreciated. Also, this particular query is being developed in Snowflake.
My current query is pulling customer volumes by department and date based on a 45 day window with a 24 day lookback from current date and a 21 day look forward based on scheduled appointments. Each date is grouped based on where it falls within that 45 day window: current week (today through next 7 days), Week 1 (forward-looking days 8-14), and Week 2 (forward-looking days 15-21). I have been working to try and build out a comparison column that, for any date that lands within either the Week 1 or Week 2 group, will pull in prior period volumes from either 14 days prior (Week 1) or 21 days prior (Week 2) but am getting nowhere. Is there a best-practice for this type of column? Generic example of the current output is attached. Please note that the 'Prior Wk' column in the sample output was manually populated in an effort to illustrate the way this column should ideally work.
I have tried several different iterations of count(case...) similar to that listed below; however, the 'Prior Wk' column returns the count of encounters/scheduled encounters for the same day rather than those that occurred 14 or 21 days ago.
Count(Case When datediff(dd,SCHED_DTTM,getdate())
between -21 and -7 then 1 else null end
) as "Prior Wk"
I've tried to use an IFF statement as shown below, but no values return.
(IFF(ENCOUNTER_DATE > dateadd(dd,8,getdate()),
count(case when ENC_STATUS in (“Phone”,”InPerson”) AND
datediff(dd,ENCOUNTER_Date,getdate()) between 7 and 14 then 1
else null end), '0')
) as "Prior Wk"
Also have attempted creating and using a temporary table (example included) but have not managed to successfully pull information from the temp table that didn't completely disrupt my encounter/scheduled counts. Please note for this approach I've only focused on the 14 day group and have not begun to look at the 21 day/Week 2 group. My attempt to use the temp table to resolve the problem centered around the following clause (temp table alias: "Date1"):
CASE when AHS.GL_Number = "DATEVISIT1"."GL_NUMBER" AND
datevisit1.lookback14 = dateadd(dd,14,PE.CONTACT_Date)
then "DATEVISIT1"."ENC_Count"
else null end
as "Prior Wk"*
I am extremely appreciative of any insight on the current best practices around pulling prior period data into a column alongside current period data. Any misuse of terminology on my part is not deliberate.
I'm struggling to understand your requirement but it sounds like you need to use window functions https://docs.snowflake.com/en/sql-reference/functions-analytic.html, in this case likely a SUM window function. The LAG window function, https://docs.snowflake.com/en/sql-reference/functions/lag.html, might also be of some help

Adjusting Overlapping Dates and Applying Other Rules

I'm trying to design a SELECT query that will modify some dates in a subset of "activity" records for each person in a table of data.
Each person is identified uniquely using "PersonID" and then each activity record using "RecordID".
Each subset of activity records a person has will also have dates against the "Start Date" and "End Date" fields.
For example, data like this (sorted by start date then longest duration):
(I've added the yellow bars to give an idea of some of the overlap and gaps between sets of dates).
Where I work, we have a task that involves adding a maximum of 1 "claim" record to associate with each of these activity records. The claim records have their own Start Date and End Date, but each claim record must:
Not cover a duration outside of the Start Date and End Date of the activity record it's being attached to.
Not overlap with the duration of any other claim record in the person's subset of claim records
Have a duration of at least 1 month, defined as either: starting on the first day of the month and ending on the last day of the month (e.g. 1/12/2018 to 31/12/2018), or starting in a month but ending in a different month (e.g. 31/12/2018 to 1/1/2019).
This is because the claim records are validated against the activity records (by an external validation tool we have no control over).
So, based on the example above, the query might output the following efficient set of dates for each activity record to use as claim records:
A brief run-down of what would happen on each record:
Record 1: For claim record 1, it used the original dates from the activity records, i.e. create a claim record that covers the entire
activity period. If working through the records in the sort order
described, it would make sense that it simply claims the full activity
period for the first claim record for each person's subset of activity
records.
Record 2: For claim record 2, NULLs have be supplied as there is no period to claim on this activity that hasn't already been claimed
in record 1.
Record 3: For claim record 3, the start date has been set to 1/12/2018, because that is the earliest date to claim from that is
both within this activity period and after the end month of the last
claim (i.e. record 1's 25/11/2019 end date).
The end date has been set to 31/12/2018. You may wonder why it is not
set to the activity's original end date of 23/1/2019. If you look
ahead to record 5, setting record 3's end date to 23/1/2019 would mean
setting record 5's start date to 1/2/2019, and it's end date would be
4/2/2019, which is not long enough to make a claim. So it would be
more efficient to stop record 3 in December so record 5 can claim both
January AND February. This may be hard to script though!
Record 4: For claim record 4, NULLs have be supplied as there is no period to claim on this activity that hasn't already been claimed
in previous claim records.
Record 5: For claim record 5, the start date has been set to 1/1/2019. See record 3 for an explanation of why.
Record 6: For claim record 6, it used the original dates from the activity records. This was just to illustrate that not all activity
records will overlap.
I'm not too sure how to approach this. I've looked at some CTE examples, but nothing that seems to match what I'm trying to do (perhaps too ambitious.. particularly the record 3 & 5 scenario?)
Any help / examples would be much appreciated.

Tableau combining rows with the same info

I have a dashboard in Tableau which shows different payments received - the amount, the date the payment was received, and a calculated field which shows the number days since the payment was received.
However, a lot of payments are the same, with the same amount, and received on the same day; so Tableau collapses these together, and adds the total days since the payments were received together in the final column, i.e. five lots of £5.50, each received on 1st January shows as below (as of 01/02/2018)
Column 1 Column 2 Column 3
£5.50 01/01/2018 155
But I need separate rows for each. Does anyone know how to stop tableau doing this, or of a workaround?
Many thanks.
You could try using RANK_UNIQUE function.
First of all, in the Analysis Menu, uncheck Aggregate Measures.
Then, starting from this data:
You can get this result:
Additionally, you may want to hide Rank from rows just not-showing header.
Is this something close to what you're looking for?
EDIT/UPDATE
In order to get all values and not just for the top rows, just move the Rank at the very beginning of the shelf: