MYSQL Master Table / Derived Table for timeseries - mysql

I have a mysql table with timestamp(YYYY-MM-DD) and value. However the timestamps are skewed - that means they are not evenly spread. Let's say I have the following table
timestamp | value
2018-01-01| 10
2018-01-15| 5
2018-01-28| 0
2018-02-03| 25
2018-04-05| 12
I want the output as average value in the past month (or week or year.)
Jan | 5
Feb | 25
March| 0
April | 12
Basically I want to create a dummy table of months or something like that and then perform an SQL query. Is this possible ? Also depending on requirement the query might change to weekly avg value or yearly avg value also.

Related

SSRS 2 column groups in matrix, 1 row reads from 1, the rest read from the other? (pls help)

Is there a way in SSRS to have an additional row within your row group, to look at a different column group than the rest of the row group
Let's say I have STATES, SALES, MONTH, and BUCKET_MONTH as my dataset fields BUCKET_MONTH is already calculated for me, based off of the MONTH. I want to show something like this:
SAMPLE DATA LIKE THIS FOR FLORIDA (and other months but BUCKET_MONTH only matters for florida let's pretend)
STATE MONTH SALES BUCKET_MONTH
FL JAN 50 FEB
FL FEB 125 FEB
FL MAR 100 MAY
FL APR 0 MAY
FL MAY 100 MAY
SSRS MATRIX MIGHT LOOK LIKE THIS: ?
| 2 groups ?
| MONTH
| BUCKET_MONTH (I can hide this header)
-----------------------------------
1 col group|
STATE | SALES
BUCKET | SALES <-- this row is only visibile for FL which I know how to do
EXPECTED RESULTS WOULD LOOK LIKE THIS
JAN FEB MAR APR MAY JUN JUL
---------------------------------------------------------------------
CA 100 300 150
FL 50 125 100 0 100
FL BUCKET 175 200 <-- BUCKET_MONTH**
MA 0 200 250 50
BUCKET_MONTH in ds shows FEB for the rows with Jan,Feb MONTH, and shows MAY for Mar,Apr, May MONTH
Is there a way to do this in SSRS? Where one of the rows looks at a different column group to establish what column to put the SUM of SALES in?
Much appreciation in advance!
You have to add BUCKET_MONTH as parent column group in your matrix.
Add BUCKET_MONTH in the Column Groups pane, then delete the created row in the matrix selecting Delete groups only option. Now add MONTH as child group in column groups pane.
Add STATE in rows group pane and add a row for bucket total.
Use this expression for BUCKET TOTAL:
=IIF(
Fields!BUCKET_MONTH.Value=Fields!MONTH.Value,
SUM(Fields!SALES.Value,"BUCKET_MONTH"),
Nothing
)
It should produce:
UPDATE: Expression updated taking in account that MONTH and BUCKET_MONTH fields are actually dates.
=IIF(
UCASE(format(Fields!BUCKET_MONTH.Value,"MMMM yy"))=
UCASE(format(Fields!MONTH.Value,"MMMM yy")),
SUM(Fields!SALES.Value,"BUCKET_MONTH"),
Nothing
)
Let me know if this helps.

Add variance in the rows of table

I've a SSRS report which should look like below,
--------------------------------
Year Product Total customers
--------------------------------
2015 prd1 100
prd2 50
prd3 60
2014 prd1 80
prd2 60
prd3 60
Varience
Prd1 20
Prd2 -10
Prd3 0
I've done the year wise grouping and the data mapping. But I'm not sure how to add variance(between 2015-2014) in each row based on the each product of the year
Update:
My dataset looks like this
Year CategoryId CategoryDesc TotalCustomerCount
2013 Prd1 Testproduct 100
2013 Prd2 Testprod2 50
2013 Prd3 Tesrprod3 45
2014 Prd1 Testproduct 80
2014 Prd2 Testprod2 60
You can see that some products may miss out in a year.
Note: The dataset is created from a Dimesional cube and not from SQL queries.
It is kind of hard to tell exactly without knowing what your current dataset looks like.
But I believe that Stanislovas' example will be of little use to you because his example only works if your dataset has a single row for each product, with columns with the total for each year. Which I'm guessing you do not have because you used row grouping to get the above result. If you did, you could've used column-grouping instead of row-grouping to get a better overview.
You have two possibilities:
Replace your current dataset completely with a dataset that has columns for each year value (like in Stanislovas' example). To achieve this kind of dataset you need your query to look like this for example:
SELECT DISTINCT(myTable.Product), t1.Total AS 'Total2014', t2.Total AS 'Total2015'
FROM myTable
JOIN (SELECT Product, SUM(Total) AS Total
FROM myTable
WHERE Year = 2014
GROUP BY Product) as t1 ON t1.Product = myTable.Product
JOIN (SELECT Product, SUM(Total) AS Total
FROM myTable
WHERE Year = 2015
GROUP BY Product) as t2 ON t2.Product = myTabel.Product
This can then be used to make a table that looks like this:
---------------------------------------
| Product | 2014 | 2015 | Variance |
---------------------------------------
| prd1 | 100 | 80 | 20 |
| prd2 | 50 | 60 | -10 |
| prd3 | 60 | 60 | 0 |
...
Or you can add a second datasource that has calculated these differences before sending it to the reporter. Here is an example to help you with your query: https://stackoverflow.com/a/15002915/4579864
If you need any more help, just leave a comment and I'll try and explain furthur. This should at least get you started.
I think the easiest way to handle this requeriment is generating the data from the query using T-SQL. However the output you require can be produced from SSRS using a dataset with the same structure as the dataset you provided in the update.
In order to recreate your scenario I used this dataset.
Year Product CategoryDesc TotalCustomerCount
2013 Prd1 Testproduct 100
2013 Prd2 Testprod2 50
2013 Prd3 Tesrprod3 45
2014 Prd1 Testproduct 80
2014 Prd2 Testprod2 60
My approach is take the minimum and maximum year values (2013 and 2014) and the product in every row and look up the TotalCustomerCount to substract it. This is a step by step guide.
First, create a calculated field in your dataset. Right click the dataset in Report Data pane, call it Year_Product and set this expression in the field source textbox.
=Fields!Year.Value & "-" & Fields!Product.Value
This will produce an additional field called Year_Product which has Year and Product fields concatenated with the - character in middle. In example: 2013-Prd1, 2014-Prd1, 2013-Prd3 etc.
Now create a tablix with this data arrangement:
In the cell highlighted in red use this expression:
=Lookup(Max(Fields!Year.Value,"DataSet13") & "-" &
Fields!Product.Value,Fields!Year_Product.Value,Fields!TotalCustomerCount.Value,"DataSet13")
-
Lookup(Min(Fields!Year.Value,"DataSet13") & "-" &
Fields!Product.Value,Fields!Year_Product.Value,Fields!TotalCustomerCount.Value,"DataSet13")
This will look up the max year and product of the row in the Year_Product field and get the TotalCustomerCount.
Year_Product: 2014-Prd1 and TotalCustomerCount: 80
Year_Product: 2013-Prd1 and TotalCustomerCount 100
The above example produces -20 since 80 - 100 = -20
It will show us repeated products because every product may be present two times. To avoid this it is necessary to sort the tablix by Product, go to tablix properties and set the below sorting option.
Now hide duplicated rows. Go to tablix properties / Row visibility and select Show or hide based on an expression.
Use this expression ton conditionally hide the duplicated products:
=IIF(
Fields!Product.Value=PREVIOUS(Fields!Product.Value),
true,
false
)
Finally if you preview the report you will see something like this (I recreated your both tables.)
Note I am using only one dataset, the same that you provide in your
question.
Hopefully this what you are looking for let me know if you need further help.

MySQL - Select row with column + X > column

We have a database for patients that shows the details of their various visits to our office, such as their weight during that visit. I want to generate a report that returns the visit (a row from the table) based on the difference between the date of that visit and the patient's first visit being the largest value possible but not exceeding X number of days.
That's confusing, so let me try an example. Let's say I have the following table called patient_visits:
visit_id | created | patient_id | weight
---------+---------------------+------------+-------
1 | 2006-08-08 09:00:05 | 10 | 180
2 | 2006-08-15 09:01:03 | 10 | 178
3 | 2006-08-22 09:05:43 | 10 | 177
4 | 2006-08-29 08:54:38 | 10 | 176
5 | 2006-09-05 08:57:41 | 10 | 174
6 | 2006-09-12 09:02:15 | 10 | 173
In my query, if I were wanting to run this report for "30 days", I would want to return the row where visit_id = 5, because it's 28 days into the future, and the next row is 35 days into the future, which is too much.
I've tried a variety of things, such as joining the table to itself, or creating a subquery in the WHERE clause to try to return the max value of created WHERE it is equal to or less than created + 30 days, but I seem to be at a loss at this point. As a last resort, I can just pull all of the data into a PHP array and build some logic there, but I'd really rather not.
The bigger picture is this: The database has about 5,000 patients, each with any number of office visits. I want to build the report to tell me what the average wait loss has been for all patients combined when going from their first visit to X days out (that is, X days from each individual patient's first visit, not an arbitrary X-day period). I'm hoping that if I can get the above resolved, I'll be able to work the rest out.
You can get the date of the first and next visit using query like this (Note that this doesn't has correct syntax for date comparing and it is just an schema of the query):
select
first_visits.patient_id,
first_visits.date first_date,
max(next_visit.created) next_date
from (
select patient_id, min(created) as "date"
from patient_visits
group by patient_id
) as first_visits
inner join patient_visits next_visit
on (next_visit.patient_id = first_visits.patient_id
and next_visit.created between first_visits.created and first_visits.created + 30 days)
group by first_visits.patient_id, first_visits.date
So basically you need to find start date using grouping by patient_id and then join patient_visits and find max date that is within the 30 days window.
Then you can join the result to patient_visits to get start and end weights and calculate the loss.

MySQL Group By Into 10 Buckets

Lets say that I have a table that looks like
1 | Test | Jan 10, 2017
...
10000 | Test | Jan 20, 2030
and I want to bucket the records in the table based on the 2nd column with a set amount of 10 buckets regardless of the values of the dates. All I require is that each bucket covers a time range of equal length.
I understand that I could do something with
GROUP BY
YEAR(datefield),
MONTH(datefield),
DAY(datefield),
HOUR(datefield),
and subtract the largest datefield with the smallest datefield and divide by 10 to get the time length covered in each bucket. However, is there already built-in functionality in MySQL that would do this as doing the manual subtraction and division might lead to smaller edge cases. Am I on the right track by doing the subtraction and division for bucketing into a constant number of buckets?

MS Access: Using Single form to enter query parameters in MS access

compliment of the day.
Based on the previous feedback received,
After creating a Ticket sales database in MS Access. I want to use a single form to Query the price of a particular ticket at a particular month and have the price displayed back in the form in a text field or label.
Below are sample tables and used query
CompanyTable
CompID CompName
A Ann
B Bahn
C Can
KK Seven
- --
TicketTable
TicketCode TicketDes
10 Two people
11 Monthly
12 Weekend
14 Daily
TicketPriceTable
ID TicketCode Price ValidFrom
1 10 $35.50 8/1/2010
2 10 $38.50 8/1/2011
3 11 $20.50 8/1/2010
4 11 $25.00 11/1/2011
5 12 $50.50 12/1/2010
6 12 $60.50 1/1/2011
7 14 $15.50 2/1/2010
8 14 $19.00 3/1/2011
9 10 $40.50 4/1/2012
Used query:
SELECT TicketPriceTable.Price
FROM TicketPriceTable
WHERE (((TicketPriceTable.ValidFrom)=[DATE01]) AND ((TicketPriceTable.TicketCode)=[TCODE01]));
In MS Access, a mini boxes pops up to enter the parameters when running the query. How can I use a single form to enter the parameters for [DATE01] and [TCODE01]. and the price displayed in the same form in a textfield (For further calculations).
Such as 'Month' field equals to input to [DATE01] parameter
'Ticket Code' equals to input for [TCODE01] parameter
Textfield equals to output of the query result (Ticket price)
If possible, I would like to use only the Month and Year in this format MM/YYYY.The day is not necessarry. How can I achieve it in MS Access?
If any question, please don't hesitate to ask
Thanks very much for your time and anticipated feedback.
You can refer to the values in the form fields by using expressions like: [Forms]![NameOfTheForm]![NameOfTheField]
Entering up to 300 different types of tickets
Answer to your comment referring to Accessing data from a ticket database, based on months in MS Access)
You can use Cartesian products to create a lot of records. If you select two tables in a query but do not join them, the result is a Cartesian product, which means that every record from one table is combined with every record from the other.
Let's add a new table called MonthTable
MonthNr MonthName
1 January
2 February
3 March
... ...
Now if you combine this table containing 12 records with your TicketTable containing 4 records, you will get a result containing 48 records
SELECT M.MonthNr, M.MonthName, T.TicketCode, T.TicketDes
FROM MonthTable M, TicketTable T
ORDER BY M.MonthNr, T.TicketCode
You get something like this
MonthNr MonthName TicketCode TicketDes
1 January 10 Two people
1 January 11 Monthly
1 January 12 Weekend
1 January 14 Daily
2 February 10 Two people
2 February 11 Monthly
2 February 12 Weekend
2 February 14 Daily
3 March 10 Two people
3 March 11 Monthly
3 March 12 Weekend
3 March 14 Daily
... ... ... ...
You can also get the price actually valid for a ticket type like this
SELECT TicketCode, Price, ActualPeriod AS ValidFrom
FROM (SELECT TicketCode, MAX(ValidFrom) AS ActualPeriod
FROM TicketPriceTable
WHERE ValidFrom <= Date
GROUP BY TicketCode) X
INNER JOIN TicketPriceTable T
ON X.TicketCode = T.TicketCode AND X.ActualPeriod=T.ValidFrom
The WHERE ValidFrom <= Date is in case that you entered future prices.
Here the subquery selects the actually valid period, i.e. the ValidFrom that applies for each TicketCode. If you find sub-selects a bit confusing, you can also store them as query in Access or as view in MySQL and base a subsequent query on them. This has the advantage that you can create them in the query designer.
Consider not creating all your 300 records physically, but just getting them dynamically from a Cartesian product.
I let you put all the pieces together now.
In Access Forms you can set the RecordSource to be a query, not only a table. This can be either the name of a stored query or a SQL statement. This allows you to have controls bound to different tables through this query.
You can also place subforms on the main form that are bound to other tables than the main form.
You can also display the result of an expression in a TextBox by setting the ControlSource to an expression by starting with an equal sign
=DLookUp("Price", "TicketPriceTable", "TicketCode=" & Me!cboTicketCode.Value)
You can set the Format of a TextBox to MM\/yyyy or use the format function
s = Format$(Now, "MM\/yyyy")