I'm not too familiar with the more complex queries and I'm having an issue finding some examples to take apart to utilize..
Event Name | Due Date | Frequency |Frequency UOM
S-XYC-001 | 10/17/2020 | 360 | D
S-XYA-003 | 6/1/2020 | 90 | D
S-XYC-004 | 4/3/2020 | 180 | D
So, we have a set of work that has an initial due date provided, and an expected frequency along with a unit of measurement (I've converted all my frequencies into days as there was previously a mix of days, quarterlies, months..).
I've been asked to generate a forecast of events in 2020. So, using the above source table we'd expect our list to look like this:
Event Name | Due Date | Frequency | Frequency UOM
S-XYC-001 | 10/17/2020 | 360 | D
S-XYA-003 | 6/1/2020 | 90 | D
S-XYA-003 | 8/30/2020 | 90 | D
S-XYA-003 | 11/28/2020 | 90 | D
S-XYC-004 | 4/3/2020 | 180 | D
S-XYC-004 | 9/30/2020 | 180 | D
I'm really not quite sure what type of query to apply to get these results, Or honestly what to look for to get some examples I can utilize to do what I need to.
First, change your frequency to months - 12, 3, and 6 respectively - to obtain the correct result dates.
Then, create a small query and save it as Ten as it simply returns 0 to 9:
SELECT DISTINCT
Abs([id] Mod 10) AS N
FROM
MSysObjects;
Use that in this generic query that is capable of generating any sequence of date/time in the entire range of DateTime:
PARAMETERS
[Interval] Text ( 255 ),
[Number] IEEEDouble,
[Date] DateTime,
[Count] IEEEDouble;
SELECT
[Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000+[Ten_7].[N]*10000000 AS Id,
DateAdd([Interval],Fix([Number])*([Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000+[Ten_7].[N]*10000000),[Date]) AS [Date]
FROM
Ten AS Ten_0,
Ten AS Ten_1,
Ten AS Ten_2,
Ten AS Ten_3,
Ten AS Ten_4,
Ten AS Ten_5,
Ten AS Ten_6,
Ten AS Ten_7
WHERE
((([Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000+[Ten_7].[N]*10000000)<[Count])
AND
(([Interval]) In ("s","n","h","d","w","ww","m","q","yyyy"))
AND
((Fix([Number])*([Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000+[Ten_7].[N]*10000000) Mod IIf(Fix([Number])=0,1,Fix([Number])))=0)
AND
((Ten_0.N)<=[Count]\1)
AND
((Ten_1.N)<=[Count]\10)
AND
((Ten_2.N)<=[Count]\100)
AND
((Ten_3.N)<=[Count]\1000)
AND
((Ten_4.N)<=[Count]\10000)
AND
((Ten_5.N)<=[Count]\100000)
AND
((Ten_6.N)<=[Count]\1000000)
AND
((Ten_7.N)<=[Count]\10000000));
Save it as DatesSequence.
This you can run with the parameters:
Interval: "m"
Number: 3, 6, or 12
Date: Due Date
Count: The count of future event dates to list
Results:
You could modify the query to filter out dates later than 2020.
Related
I have a MySQL table named rbsess with columns RBSessID (key), ClientID (int), RBUnitID (int), RentAmt (fixed-point int), RBSessStart (DateTime), and PrevID (int, references to RBSessID).
It's not transactional or linked. What it does track when a client was moved into a room and what the rent at the time of move in was. The query to find what the rent was for a particular client on a particular date is:
SET #DT='Desired date/time'
SET #ClientID=Desired client id
SELECT a.RBSessID
, a.ClientID
, a.RBUnitID
, a.RentAmt
, a.RBSessStart
, b.RBSessStart AS RBSessEnd
, a.PrevID
FROM rbsess a
LEFT
JOIN rbsess b
ON b.PrevID=a.RBSessID
WHERE a.ClientID=#ClientID
AND (a.RBSessStart<=#DT OR a.RBSessStart IS NULL)
AND (b.RBSessStart>#DT OR b.RBSessStart IS NULL);
This will output something like:
+----------+----------+----------+---------+---------------------+-----------+--------+
| RBSessID | ClientID | RBUnitID | RentAmt | RBSessStart | RBSessEnd | PrevID |
+----------+----------+----------+---------+---------------------+-----------+--------+
| 2 | 4 | 1 | 57500 | 2020-11-22 00:00:00 | NULL | 1 |
+----------+----------+----------+---------+---------------------+-----------+--------+
I also have
SELECT * FROM rbsess WHERE rbsess.ClientID=#ClientID AND rbsess.PrevID IS NULL; //for finding the first move in date
SELECT TIMESTAMPDIFF(DAY,#DT,LAST_DAY(#DT)) AS CountDays; //for finding the number of days until the end of the month
SELECT DAY(LAST_DAY(#DT)) AS MaxDays; //for finding the number of days in the month
SELECT (TIMESTAMPDIFF(DAY,#DT,LAST_DAY(#DT))+1)/DAY(LAST_DAY(#DT)) AS ProRateRatio; //for finding the ratio to calculate the pro-rated rent for the move-in month
SELECT ROUND(40000*(SELECT (TIMESTAMPDIFF(DAY,#DT,LAST_DAY(#DT))+1)/DAY(LAST_DAY(#DT)) AS ProRateRatio)) AS ProRatedRent; //for finding a pro-rated rent amount based on a rent amount.
I'm having trouble putting all of these together to form a single query that can output pro-rated and full rent amounts based on a start date and an optional end date all rent owed amounts in a single statement for each month in the period. I can add a payments table received and integrate it afterwards, just having a hard time with this seemingly simple real-world concept in a MySQL query. I'm using php with a MySQL back end. Temporary tables as intermediary queries are more than acceptable.
Even a nudge would be helpful. I'm not super-experienced with MySQL queries, just your basic CREATE, SELECT, INSERT, DROP, and UPDATE.
Examples as requested by GMB:
//Example data in rbsess table:
+----------+----------+----------+---------+---------------------+--------+
| RBSessID | ClientID | RBUnitID | RentAmt | RBSessStart | PrevID |
+----------+----------+----------+---------+---------------------+--------+
| 1 | 4 | 1 | 40000 | 2020-10-22 00:00:00 | NULL |
| 2 | 4 | 1 | 57500 | 2020-11-22 00:00:00 | 1 |
| 3 | 2 | 5 | 40000 | 2020-11-29 00:00:00 | NULL |
+----------+----------+----------+---------+---------------------+--------+
Expected results would be a list of the rent amounts owed for every month, including pro-rated amounts for partial occupancy in a month, from a date range of months. For example for the example data above for a date range spanning all of the year of 2020 from client with ClientID=4 the query would produce an amount for each month within the range similar to:
Month | Amt
2020-10-1 | 12903
2020-11-1 | 45834
2020-12-1 | 57500
I'm trying to add a column to a production hours dataset that will tell if a provider who worked last week was also working three weeks earlier. The current dataset looks something like this:
RowID | ProviderID | ClientID | DOS | DOS (Week) | Hours
1 | 1111111111 | 22222222 | 11/2/2020 | 11/1/2020 | 2.5
2 | 1111111111 | 33333333 | 11/5/2020 | 11/1/2020 | 1
3 | 1111111111 | 44444444 | 10/13/2020 | 10/11/2020 | 3
I'm trying to get an extra column 'Active 3 Weeks Prior' with y/n or 1/0 for values. For the above table, let's assume the provider started on 10/13/20. The new column would ideally populate like this:
RowID | ProviderID | ClientID | DOS | DOS (Week) | Hours | Active 3 weeks Prior
1 | 1111111111 | 22222222 | 11/2/2020 | 11/1/2020 | 2.5 | Yes
2 | 1111111111 | 33333333 | 11/5/2020 | 11/1/2020 | 1 | Yes
3 | 1111111111 | 44444444 | 10/13/2020 | 10/11/2020 | 3 | No
A couple extra tidbits: our org uses Sunday as the start of the week so DOS (Week) is the Sunday prior to the date of service. From what I've been reading so far, it seems like the solution here is some kind of self join, where the base production records are aggregated into weekly hours and compared with that same providerID's records for DOS (Week) - 21.
The trouble I'm having is: whether I'm on the right track in the first place with the self-join and how I would generate the y/n values based on the success or failure to find a matching value. Also, I suspect that joining based on a concatenate of ProviderID and DOS(Week) might be flawed? This is what I've been playing with so far.
Please let me know if I can clarify the question at all or am missing something very obvious. I truly appreciate any help, as I've been trying to figure out the right search terms to get a clue on the answer for a few days now.
If you are running MySQL 8.0, you can use window functions and a range specification:
select t.*,
(
max(providerid) over(
partition by providerid
order by dos
range between interval 3 week preceding and interval 3 week preceding
) is not null
) as active_3_weeks_before
from mytable t
It is not really clear from your explanation and data what you mean by was also working three weeks earlier. What the query does is, for each row, to check if another row exists with the same supplier and a dos that is exactly 3 week before the dos of the current row. This can easily be adapted for some other requirement.
Edit: if you want to check for any record within the last 3 weeks, you would change the window range to:
range between interval 3 week preceding and interval 1 day preceding
And if you want this in MySQL < 8.0, where window functions are not available, then you would use a correlated subquery:
select t.*,
exists (
select 1
from mytable t1
where
t1.providerid = t.provider_id
and t1.dos >= t.dos - interval 3 week
and t1.dos < t.dos
) as active_3_weeks_before
from mytable t
I am currently trying to set up a query in Grafana to display a graph. I have data in the database and my query returns the results I expect, but the graph seems to only display the smallest result.
Table [test_statements]
| ID | ReportTime | LapTime |
| 1 | 2018-03-29 13:02:06 | 2700 |
| 2 | 2018-03-29 13:03:06 | 2725 |
| 3 | 2018-03-29 13:04:06 | 1645 |
| 4 | 2018-03-29 13:05:06 | 2900 |
| 5 | 2018-03-29 13:06:06 | 3101 |
The template is structured as:
SELECT UNIX_TIMESTAMP(<time_column>) as time_sec,
<value column> as value,
<series name column> as metric
FROM <table name>
WHERE $__timeFilter(time_column)
ORDER BY <time_column> ASC
Current Query
SELECT
UNIX_TIMESTAMP(ReportTime) as time_sec,
LapTime as value,
'ReportTime' as metric
FROM test_statements
WHERE ReportTime > 0
ORDER BY ReportTime ASC
Here are my results:
I can see the ReportTime results are correct, but the graph is wrong.
Not sure what i'm doing wrong but a point in the correct direction would be helpful. Thanks.
Since there are no time scale labels on x-axis in screenshot
most likely you have Format as in graph editor's Metrics tab set to Series or Table instead of Time series.
Thus, what you see as y-axis value is the total (sum) of your individual datapoint values (approx. 7 * 2.7K) which is the default setting for series aggregation function. And x-axis is labeled with time series name(metric).
I'm having a hard time making a MySQL statement from a Postgres one for a project we are migrating. I won't give the exact use case since it's pretty involved, but I can create a simple comparable situation.
We have a graphing tool that needs somewhat raw output for our data in hourly intervals. In Postgres, the SQL would generate a series for the date and hour over a time span, then it would join a query against that for the average where that date an hour existed. We were able to get for example the average sales by hour, even if that number is 0.
Here's a table example:
Sales
datetime | sale
2017-12-05 08:34:00 | 10
2017-12-05 08:52:00 | 20
2017-12-05 09:15:00 | 5
2017-12-05 10:22:00 | 10
2017-12-05 10:49:00 | 10
Where something like
SELECT DATE_FORMAT(s.datetime,'%Y%m%d%H') as "byhour", AVG(s.sale) as "avg sales" FROM sales s GROUP BY byhour
would produce
byhour | avg sales
2017120508 | 10
2017120509 | 5
2017120510 | 10
I'd like something that gives me the last 24 hours, even the 0/NULL values like
byhour | avg sales
2017120501 | null
2017120502 | null
2017120503 | null
2017120504 | null
2017120505 | null
2017120506 | null
2017120507 | null
2017120508 | 10
2017120509 | 5
2017120510 | 10
...
2017120600 | null
Does anyone have any ideas how I could do this in MySQL?
Join the result on a table that you know contains all the desired hours
someting like this:
SELECT
* FROM (
SELECT
DATE_FORMAT(s.datetime, '%Y%m%d%H') AS 'byhour'
FROM
table_that_has_hours
GROUP BY byhour) hours LEFT OUTER JOIN (
SELECT
DATE_FORMAT(s.datetime, '%Y%m%d%H') AS 'byhour',
AVG(s.sale) AS 'avg sales'
FROM
sales s
GROUP BY byhour) your_stuff ON your_stuff.byhour = hours.by_hours
if you don't have a table like that you can create one.
like this:
CREATE TABLE ref (h INT);
INSERT INTO ref (h)
-> VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),
-> (12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)
and then you can just DATE_FORMAT(date(now()),'%Y%m%d%H') to the values
help me, please!
At the table - date, time, person, source. Updated with new values when employee passing through the checkpoint, he can leave / came several times per day.
+---------------+----------+--------+-------------+
| date | time |person |source |
+---------------+----------+--------+-------------+
| 01.08.2014 | 08:42:08 | Name1 | enter1 |
+---------------+----------+--------+-------------+
| 01.08.2014 | 09:42:12 | Name1 | exit1 |
+---------------+----------+--------+-------------+
| 01.08.2014 | 10:22:45 | Name1 | enter2 |
+---------------+----------+--------+-------------+
| 01.08.2014 | 18:09:11 | Name1 | exit2 |
+---------------+----------+--------+-------------+
I need to count for each employee the actual time he spent at work each day. Table will always be not editable. It is formed from a csv file. The script runs once.
I think need to do something like this:
TIMESTAMPDIFF(MINUTE, enterTime, exitTime)
for each employee for 1 day. But I have a very poor knowledge in sql.
The date/time formats should be stored in a datetime/timestamp column. It is possible to convert them, although ugly (there's probably a better way...):
> SELECT CONCAT(STR_TO_DATE('01.08.2014', '%m.%d.%Y'), ' ', '08:42:08');
2014-01-08 08:42:08
Now Suppose the times are unix timestamps. An employ arrives at t0 and leaves at t1. The time he was at work is (t1-t0) seconds. Now suppose he he arrives at t0, leaves for a break at t1, returns at t2, and leaves for the day at t3. His total time at work is (t1-t0) + (t3-t2) = (t1+t3)-(t0+t2). In general: his time at work for a given day is the sum of the arrival times subtracted from the sum of the departure times.
Using your times:
1389188528 enter1
1389192132 exit1
1389194565 enter2
1389222551 exit2
We see that total time at work is: 1389222551 + 1389192132 - (1389188528 + 1389194565) = 31590, or about 8 hours and 47 minutes. Now what remains is converting to unix timestamps (UNIX_TIMESTAMP()) and applying this reasoning via SQL. In the following example, I have added your data to a table named work_log and assumed that when source begins with exit or enter, we are respectively referring to a departure or arrival.
SELECT person, DATE(dt) AS day,
SUM(IF(`source` like 'enter%', -1, 1)*UNIX_TIMESTAMP(dt))/3600 AS hours
FROM (SELECT CONCAT(STR_TO_DATE(`date`, '%m.%d.%Y'), ' ', `time`) AS `dt`,
`person`,`source` FROM work_log) AS wl
GROUP BY person,day;
+--------+------------+--------------+
| person | day | hours |
+--------+------------+--------------+
| Name1 | 2014-01-08 | 8.7750000000 |
+--------+------------+--------------+
1 row in set (0.00 sec)
There are probably cleaner ways of doing that.