SQL - Update groups of data based on start and end dates - sql

I have a table with dates of service for various hospital stays and want to update the starting and end dates for each claim to match the length of the entire stay. The table below has seven inpatient stays and dates of service for each of those stays. A min_max flag of 1 or 2 means that the dates in that row cover the entire length of that specific stay (each stay is color-coded).
Current table image here
I need to updated the dates for all rows within each colored grouping to match the starting and end dates for the row which has a min_max flag of 1 or 2 within the same group to ultimately find the sum of claims in each stay. I could do this manually here or in excel but I need it done on a much larger scale with thousands of hospital stays.
Goal table here
TIA!

Related

Microsoft Access- How to create dynamic variables that queries a selection of Columns

Example Data Picture
My main data table is constructed in the following way:
1.State
2.Product
3.Account Name
4.Jan-20
5.Feb-20
.
.
.
N.)Recent Month- Recent Year
My goal is to get 6 total sums based on 6 different contiguous that are user selected. For example, if someone wanted the value of an Account Given a State and Product for FY-2020, they would sum columns 4 to column 15 (Twelve Months).
I am going to be running joins and queries off of the State, Product, Account combinations (first three columns), but I need to create a method to sum the Data table given a list of Column Numbers.
At this point, I am not looking to put non-contiguous columns in a selected Time Period (i.e. all time period selections will be from Col.Beg_TPn to and including Col.End_TPn). The Data Table houses monthly data that will have one new column every month. The Column Number should stay consistent as we are not looking back further than FY-2020.
This a much easier problem in Excel as you can do a simple SumIfs with an Index of the Column Range as the SumRange and then you filter on Columns 1,2,3. My data table is about 30,000 rows, so Excel freezes on me when could calculations and functions on the entire data set.
What is the best way to go about this in Microsoft Access? Ideally, I would like to create a CTE_TimePeriodTotals that houses the First 3 Columns (State,Product,Account) and then 6 TP Columns (tp-1,tp-2...) that holds the sum of each time period for each row based on the Time Period Column Starts and Time Period Column End.

Group or Sum the data based on overlapping period

I'm working on migrating legacy system data to a new system. I'm trying to migrate the data with history based on changed date. My current query results to below output.
Since it's a legacy system, some of the data falls within same period. I want to group the data based on id and name, and add the value as active record or inactive based on the data falls under same period.
My expected output:
For example, lets take 119 as an example and explain the same. One row marked as yellow since its not falls any overlapping period between other rows, but other two rows overlaps the period 01-No-18 to 30-Sep-19.
I need to split the data for overlapping period, and add the value only for overlapped period. So I need to look for combination based on date, which results to introduce a two rows one for non overlapped which results to below two rows
Another row for overlapped row
Same scenario applied for 148324, two rows introduced, one for overlapped and another non overlapped row.
Also is it possible to get non-overlapped data alone based on any condition ? I want to move overlapping data alone to temp table, and I can move the non-overlapped data directly to output table.
I think I dont have 100% solution, but its hard to decision what data are right and how them sort.
This query is based on lead/lag analytic functions. I had to change NULL values to adequate values in sequence (future and past).
Please try and modify this query and I hope it will fit in your case.
My table:
Query:
SELECT id,name,value,startdate,enddate,
CASE WHEN nvl(next_startdate,29993112)>nvl(prev_enddate,19900101) THEN 'Y' ELSE 'N' END AS active
FROM
(
SELECT datatable.*,
lag(enddate) over (partition by id,name order by startdate,value desc) prev_enddate,
lead(startdate) over (partition by id,name order by startdate,value desc) next_startdate
FROM datatable
) dt
Results:

how to group rows based on a dates in a single column

I have a range of date (A1:CY7026) with a column for start dates. this column has a large amount of repeated dates within it. i need these dates group together based on the working week they are located in (eg. all values reading 16/7/18 - 22/07/18 would be one group and the following week would make up another).
Use below in B2 cell (Suppose you had a header column) and drag to the rest. Sort to obtain the desired result.
=CONCATENATE(YEAR(A2),"-",WEEKNUM(A2))

storing data ranges - effective representation

I need to store values for every day in timeline, i.e. every user of database should has status assigned for every day, like this:
from 1.1.2000 to 28.05.2011 - status 1
from 29.05.2011 to 30.01.2012 - status 3
from 1.2.2012 to infinity - status 4
Each day should have only one status assigned, and last status is not ending (until another one is given). My question is what is effective representation in sql database? Obvious solution is to create row for each change (with the last day the status is assigned in each range), like this:
uptodate status
28.05.2011 status 1
30.01.2012 status 3
01.01.9999 status 4
this has many problems - if i would want to add another range, say from 15.02.2012, i would need to alter last row too:
uptodate status
28.05.2011 status 1
30.01.2012 status 3
14.02.2012 status 4
01.01.9999 status 8
and it requires lots of checking to make sure there is no overlapping and errors, especially if someone wants to modify ranges in the middle of the list - inserting a new status from 29.01.2012 to 10.02.2012 is hard to implement (it would require data ranges of status 3 and status 4 to shrink accordingly to make space for new status). Is there any better solution?
i thought about completly other solution, like storing each day status in separate row - so there will be row for every day in timeline. This would make it easy to update - simply enter new status for rows with date between start and end. Of course this would generate big amount of needless data, so it's bad solution, but is coherent and easy to manage. I was wondering if there is something in between, but i guess not.
more context: i want moderator to be able to assign status freely to any dates, and edit it if he would need to. But most often moderator will be adding new status data ranges at the end. I don't really need the last status. After moderator finishes editing whole month time, I need to generate raport based on status on each day in that month. But anytime moderator may want to edit data months ago (which would be reflected on updated raports), and he can put one status for i.e. one year in advance.
You seem to want to use this table for two things - recording the current status and the history of status changes. You should separate the current status out and move it up to the parent (just like the registered date)
User
===============
Registered Date
Current Status
Status History
===============
Uptodate
Status
Your table structure should include the effective and end dates of the status period. This effectively "tiles" the statuses into groups that don't overlap. The last row should have a dummy end date (as you have above) or NULL. Using a value instead of NULL is useful if you have indexes on the end date.
With this structure, to get the status on any given date, you use the query:
select *
from t
where <date> between effdate and enddate
To add a new status at the end of the period requires two changes:
Modify the row in the table with the enddate = 01/01/9999 to have an enddate of yesterday.
Insert a new row with the effdate of today and an enddate of 01/01/9999
I would wrap this in a stored procedure.
To change a status on one date in the past requires splitting one of the historical records in two. Multiple dates may require changing multiple records.
If you have a date range, you can get all tiles that overlap a given time period with the query:
select *
from t
where <periodstart> <= enddate and <periodend> >= effdate

How to group within groups in Access

I've been trying for a while and I'm just about to give up. I need to prepare a report that displays Item Numbers, the line they were produced on, and their production date, among other things. So, as you would imagine, each row contains a line number, item number, production date, and information regarding the number of items planned and produced for that entry.
I need to group the rows by line first, that was simple enough, afterwards, I need to group them by week, that also worked like a charm, except the dates were not really in order after this. I would need to apply a sort but by day this time. This works well but it's the next step that causes the most trouble. I also need to group the runs of items produced. For example:
Day - Item
Day 1 - Item A
Day 2 - Item A
Day 3 - Item A
These would be grouped with a footer counting the number of items produced for those consecutive entries. However, sometimes production looks like this:
Day - Item
Day 1 - Item B
Day 2 - Item B
Day 3 - Item A
Day 3 - Item B
I don't see a way to have the items ordered in a particular way that they can be grouped since I'm already ordering/sorting them by date because the date order is messed up by the first group. If I'm to group items at that point I would get one group header/footer per row, meaning it's not working at all.
My client suggests I make it so that when Access "notices the item number changes it gives a total". While that's wonderful in words, it implies that the rows should be sorted by item number and date. He will produce item A for three days, then produce item B for 2 days but part of the problem is that sometimes he will produce A for two and a half days and start B on that third day (following A) so if it's ordered by date, it may put one row above the other since they are on the same day. To my knowledge there is no real way to have Access to just "know" which products are produced first so as to group them after the item number changes. Of course it can keep the order they were entered in but if I ever need them sorted, that order will be lost.
I'm not sure if this is at all possible with this kinda of table structure. If not, can anyone suggest an alternative table structure? Or perhaps there's a way to have the first group by to not mess up the dates, which would allow me to remove the sort by date (although I'm not sure that it would work even if I could do that).
#Steve Kass
Day - Item
Day 1 - Item B
Day 2 - Item B
Day 3 - Item B
Day 3 - Item A
Day 3 - Item C
Day 4 - Item A
Day 5 - Item C
This is how it's laid out in his Excel sheet:
Day - Item
Day 1 - Item B
Day 2 - Item C
Day 3 - Item C
Day 3 - Item A
Day 4 - Item A
Day 4 - Item D
Day 5 - Item D
I've picked letters that represent the alphabetical order of the actual item numbers.
#Abe Miessler, Query so far:
SELECT Planned.Line,
Planned.[Production Date],
Items.[Item Number],
Items.[Bottles/Pallet],
Planned.PQ1,
Planned.AQ1,
Planned.PQ2,
Planned.AQ2,
Planned.PQ3,
Planned.AQ3
FROM Items
INNER JOIN Planned
ON Items.ID = Planned.ItemID;
#David-W-Fenton: Well I'm being asked to have a production summary per run. A run would be described as consecutive production of the same product. Products are produced on one of two lines and there can be multiple entries per day. The report must be grouped first by line so that each group shows entries for that line. That was done with a simple grouping. Within each line grouping I'm required to separate entries by week. Now, within each week, the days are not appearing in order. If the days are not in order we will not see a run simply because a run will most likely happen with consecutive days. One product will be produced for 3 days in a row for example, if these days are mixed up with the other days of the week, there will not be a consecutive, identifiable run. To have the entries in each week be in the correct order (by day) I applied a sort. What I've noticed is that after applying this sort each entry is handled as a separate "group" but without a header/footer. This results in not being able to group by product number afterwards since each entry is within its own "group".
I think you're asking for something impossible. But just in case you aren't, please let us know what order you want if these are your rows:
Day - Item
Day 1 - Item B
Day 2 - Item B
Day 3 - Item A
Day 3 - Item B
Day 3 - Item C
Day 4 - Item A
Day 5 - Item C
You say in a comment that you started with this:
Group by=>line
Group by=>week
Group by=>product number
...but it didn't work "because after grouping by week, they're grouped by week but within the week they're no longer ordered." So you (correctly) added a sorting group, thus:
Group by=>line
Group by=>week
Sort by=>day
Group by=>product number
But you say:
Now it's in order and you can see
consecutive days with the same
products but grouping results in each
row being grouped separately.
Where are the controls displaying the data? In the detail or in the group/sort header? It makes all the difference in the world. To display all records, you use the DETAIL. To show summary data, you use the HEADER. It sounds to me like you're putting your controls in the header instead of the detail.
Can you take a screenshot of your report in design view and insert it into your question? Without it, I don't see how to get any further.