SQL Aggregate Subtotal - sql

DATE|Sales
1|2
1|3
2|2
2|4
2|2
3|3
4|4
4|5
5|3
5|3
6|3
7|2
7|2
I have a table which is in this format. The first column is the date and the second one is the sales in dollars.
The table is 2 million rows.
So from the above table we can get that
after the first day we gained 5$
after the second day we gained 13$
after the third day we gained 16$
after the fourth day we gained 25$
after the fifth day we gained 31$
after the sixth day we gained 34$
after the seventh day we gained 38 $
What i want is to create a function to calculate the sales from one specific day (this date would be the input parameter to the function) to the most recent date to the table.
For example i would like to calculate the sales after the 5th 6th and 7th of the month.
Imagine that my table is two million rows and the dates instead of 3 (like in the previous case e.g.5th 6th and 7th) they might me thousands. Which is the most efficient way of doing that ?

Well, it sounds like you're basically going to be doing a table scan no matter what, it's just you need to start part-way down. I'm guessing the timestamp is indexed? Try doing WHERE date > START_DATE, and then you just do a sum(sales) as usual. Not sure that there's a more efficient way.

Related

Cumulative count in SQL

I am working on SQL and came across one scenario that needs to build in SQL.
Below is scenario:
PatientID AdmitDate DischargeDate
12 7/24/2017 09:45 7/24/2017 11:01
13 7/21/2016 08:37 7/22/2017 00:15
I want result set as below:
For patientID 13, count is calculated in first 2 rows and
For patientid 12, count is calculated in last row.
Well, that looks like whatever you do will be slow. I think I'd use a tally table. The table, instead of just containing the usual n years worth of dates / days / day of week etc. would also contain one record for each hour in the day. The Primary Key would represent one of those segments.
Then you could pass the admission date and discharge date for a patient to a function that would return a list, or range, of the hours that the patient is in for. So, Patient 13 might get a return value of (for example) 1500,1517 (i.e the patient was in for 17 hours and you will know the date and time because 1500 will be the Primary Key of a record that gives you the date and hour of the day he was admitted). Patient 12 would (to continue the example) return a value of 1544,1546
You could then build the dataset from Date A to Date B by returning all the data between those dates from the tally table and then check whether each hour is a yes or no for a particular patient.
The display of the data - your desired result set - I would do in somewhere else. I'd probably return two datasets. One would be used to build your table structure. The other would be used to decide whether to put a '1' in the box or not. You could do your summing on the fly.
I imagine this would get interesting with patients on the same dates ... you'd have to show each patient separately?

Get last hours records in select statement

I have a table of machines in which I will display in the first row the actual scrap, in the second row the scrap from last 1 hour, in the third row the scrap from last 4 hours and in the last row the scrap from last 8 hours.
I thought to create in SSRS 4 Datasets for each hours needed. But I think there is a easier way to do it in one Dataset.
Can I do it in the select statement for each hour per one expression?
From what I can gather from your question, your select statement needs to be filtered to the last 8 hours. You can then add a new column for which "Type" it is - last hour, last four hours, last 8 hours. Then group by this in a tablix in SSRS.

Given starting Year and Month as separate columns, how to tell if a specific year and month are within next 6 months?

I have a table A with two columns named Year and Month. I need to join it with another table B also with Year and Month columns. The condition I need to impose is that the month in B is within next 6 months of the month in A. For example, if A.Year=2014 and A.Month=09, then B.Year=2015 and B.Month=01 would be selected because it is within the next 6 months.
I've searched on SO but have not been able to find a solution. This thread
gave me a hint of using Year*100+Month calculations. But I am not sure how to add 6 months to such a calculation easily (guess I could use modulo). Does anyone have a good clean solution to this?
Instead of Year*100+Month simply use Year*12+Month.
WHERE B.Year*12+B.Month BETWEEN A.Year*12+A.Month AND A.Year*12+A.Month +6

rearrange SQL data to different view

I have a database table with product, salesvolume, date and a timestamp in SQL server.
I have data in tables as:
date product time volume
10-28-2014 a 15:05 5
10-28-2014 a 16:06 8
10-28-2014 b 9:05 3
Required format:
date product h10 h16 h17
"10-28-2014" a 5 8
"10-28-2014" b 3
From this I want to create a new table/view in which I have total sales per day, per product, per hour of the day.
So i'll have 24 columns, 1 per hour of the day and one record for every day for every product.
Is this possible to create with just SQL? any tips how to do this?
Thank you!
I'm sorry but can't get the table layout to work...
You want to first of all group your data by day, hour (which you can extract from your time-stamp field), product and sum by sales.
From this you can then use the pivot function to cross-tab your hour field - you'll find plenty of documentation about the pivot functionality on-line.

When a start date and end date span more than one week, I need to split a row up in 2 or more new rows

I would like to begin by saying I'm quite new to sql.
That said, here is my question/problem:
I have a view that has two date columns, a variable column and a text column (for comments).
I need to be able to split up all rows where the two dates are not in the same week. And I need to be able to split the variable value as well, so that it gets evenly distributed, based on how many days were in each week. The comment must be copied as well, so to be shown in each row.
My dataset looks like this:
DateIn DateOut Amount Comment
2014-11-01 2014-11-08 600 Good
And what I want is this:
DateIn DateOut Amount Comment
2014-11-01 2014-11-07 525 Good
2014-11-08 2014-11-08 75 Good
And if the time period spreads over more weeks, I would need it to split up to equivalent number of rows.
I would be very greatful if somebody could take the time to tell me how to achive my goal, using an sql-query.
As this is my first post on the forum, I apologize for any format errors in my post.
First, you need a weeks table. I mean physical table or view, where exists one row for every week possible. (We have dates table here, +/- 30 years from now - allows easily create weeks view and similar).
Then you need link your data to weeks table with left join; join condition should check date ranges overlap with week date range (probably you have to have both week start and week end fields in your weeks table - makes comparisons easier).
Then you need to divide amounts between weeks. Because you know date range length, week length and overlapping date range length, this should be trivial :)