SQL Query to show a specific date only once - mysql

I am working on a WordPress site where I have to create a table using values from MySQL, something like 'https://alerts.flexoffers.com/v2/PublisherLog'.
What I have achieved right now shows all the entries on the base of warning or error. This means there will be multiple entries each day telling if it is an error or a warning.
What I need is that there is only one entry for a specific date in the date column. And then in respective warning and error columns, all the entries from that day add up and show the number of errors/warnings there were.
SELECT bctw_error_logs.`id`,
SUM(if(bctw_error_logs.`severity_level` = '1', 1, 0)) as Warnings,
SUM(if(bctw_error_logs.`severity_level` = '2', 1, 0)) as Errors,
DAYNAME(`log_date`) as Day,
DATE_FORMAT(`log_date`, "%M %d %Y") as Date
FROM bctw_error_logs group by bctw_error_logs.`id`;
This what I am using right now.

Related

Error when runing query from form between two date from a form

I have a form called FirstInLastOut which looks as the image below.
Based on Name or badge number I want to search between two dates.
I am using the following criteria on the query:
>=[Forms]![FirstInLastOut]![StartDateEntry] And <=[Forms]![FirstInLastOut]![EndDateEntry]
This is given me results that include other months as well. Please see the query report below.
So as you can see in the image the numbers of the dates are falling with the the parameter but getting other months as well.
How can I make it so it will only select the dates between the date ranges?
SELECT FistClockInRaw.Badgenumber, FistClockInRaw.name, FistClockInRaw.lastname, FistClockInRaw.MinOfCHECKTIME, FLastClockOutRaw.MaxOfCHECKTIME, [MaxOfCHECKTIME]-[MinOfCHECKTIME] AS TotalHours, FLastClockOutRaw.QDate, FistClockInRaw.MinOfQTime, FLastClockOutRaw.MaxOfQTime, RawCompleteQuery.CHECKTIME
FROM RawCompleteQuery, FLastClockOutRaw INNER JOIN FistClockInRaw ON (FLastClockOutRaw.Badgenumber = FistClockInRaw.Badgenumber) AND (FLastClockOutRaw.name = FistClockInRaw.name) AND (FLastClockOutRaw.QDate = FistClockInRaw.QDate)
WHERE (((FistClockInRaw.name)=[Forms]![FirstInLastOut]![FirstNameEntry]) AND ((RawCompleteQuery.CHECKTIME)>=[Forms]![FirstInLastOut]![StartDateEntry] And (RawCompleteQuery.CHECKTIME)<=[Forms]![FirstInLastOut]![EndDateEntry]));
is the Query
I assume that the forms fields StartDateEntry and EndDateEntry are bound to fields of type date.
I also assume that you are only interested to compare the date part of those form fields.
So try this condition instead to assure correct date interpreting:
WHERE FistClockInRaw.name=[Forms]![FirstInLastOut]![FirstNameEntry]
AND RawCompleteQuery.CHECKTIME >= Format([Forms]![FirstInLastOut]![StartDateEntry], "\#yyyy-mm-dd\#")
AND RawCompleteQuery.CHECKTIME <= Format([Forms]![FirstInLastOut]![EndDateEntry], "\#yyyy-mm-dd\#")
A remark:
Be aware that every date field/variable always contains a time part too!
So your current logic comparing EndDateEntry with <= can cause trouble, because you would only get results of the end date having time values of 00:00:00 in the field CHECKTIME.
If any record of CHECKTIME contains the requested end date and a time part bigger then 00:00:00, it is not in the result.
To avoid that, you should use < and add one day:
And RawCompleteQuery.CHECKTIME < Format([Forms]![FirstInLastOut]![EndDateEntry] + 1, "\#yyyy-mm-dd\#")

Get the running total of a column filtered by month and year

I have a MySQL database table called user_inputs with userId(str), year(int), month(int) and input(int) columns.
I need to get the last 12 months of record per user, and get the sum of the input column.
So far I came up with the following:
CREATE TEMPORARY TABLE temp
AS (SELECT *, CAST(CONCAT(`year`, '-', `month`, '-01' ) AS DATE) AS `NewDate` FROM `user_inputs`);
SELECT `userId`, SUM(`input`) AS `running_total` FROM temp
WHERE `userId` = 266
AND `NewDate` BETWEEN STR_TO_DATE(CONCAT('2018', '01', '01'), '%Y%m%d')
AND LAST_DAY(STR_TO_DATE(CONCAT('2018', '12', '01'), '%Y%m%d'));
Is there a way this two statements could be simplified and combined into one, without having to create a temporary table? The goal is to be able to filter the results using a beginning month/year and ending month/year combinations and get the sum of inputs from the result.
Note: I've decided to just add a generated column that combines the month and year columns.

How do I subtract two dates that are in rows (not given in the query) Mysql

Say you're designing a system for a library and you want two dates to be subtracted - the checkout date and the checkin date. I have a file with both of these dates along with the video id and customer id. I also want to sort by 7 or more days (the book is due today or past due).
I had something like this, which worked up until the date parts:
SELECT customers.first_name, customers.last_name, video_checkout.checkout_date,
video_checkout.checkin_date FROM video_rental, customers, video_checkout
WHERE video_checkout.checkout_date - video_checkout.checkin_date >= 7;
So I decided to try a date_sum and TIMESTAMPDIFF, but after 2 hours of Googling, it doesn't seem that date_sums or TIMESTAMPDIFFS support subtracting two dates from tables.
Is there anyway to subtract dates that are in tables? Can I create a query that will return the subtracted dates, video id and customer id for many entries?
Using Mysql Workbench 6.3.4
The dates are in the video checkout file like this:
DELETE FROM video_checkout;
INSERT INTO video_checkout VALUES (
'1',
'1',
'2015-08-20',
'2015-08-30'
);
INSERT INTO video_checkout VALUES (
'1',
'5',
'2015-08-19',
'2015-08-29'
);
In the end I want it to look something like this:
Firstname | Lastname | Due date
Something like this
SELECT customers.first_name, customers.last_name, video_checkout.checkout_date,
video_checkout.checkin_date FROM video_rental, customers, video_checkout
WHERE DATEDIFF (video_checkout.checkout_date, video_checkout.checkin_date) >= 7;

MySQL Group By Order and Count(Distinct)

What is the best way to think about the Group By function in MySQL?
I am writing a MySQL query to pull data through an ODBC connection in a pivot table in Excel so that users can easily access the data.
For example, I have:
Select
statistic_date,
week(statistic_date,4),
year(statistic_date),
Emp_ID,
count(distict Emp_ID),
Site
Cost_Center
I'm trying to count the number of unique employees we have by site by week. The problem I'm running into is around year end, the calendar years don't always match up so it is important to have them by date so that I can manually filter down to the correct dates using a pivot table (2013/2014 had a week were we had to add week 53 + week 1).
I'm experimenting by using different group by statements but I'm not sure how the order matters and what changes when I switch them around.
i.e.
Group by week(statistic_date,4), Site, Cost_Center, Emp_ID
vs
Group by Site, Cost_Center, week(statistic_date,4), Emp_ID
Other things to note:
-Employees can work any number of days. Some are working 4 x 10's, others 5 x 8's with possibly a 6th day if they sign up for OT. If I sum the counts by week, I get anywhere between 3-7 per Emp_ID. I'm hoping to get 1 for the week.
-There are different pay code per employee so the distinct count helps when we are looking by day (VTO = Voluntary Time Off, OT = Over Time, LOA = Leave of Absence, etc). The distinct count will show me 1, where often times I will have 2-3 for the same emp in the same day (hits 40 hours and starts accruing OT then takes VTO or uses personal time in the same day).
I'm starting with a query I wrote to understand our paid hours by week. I'm trying to adapt it for this application. Actual code is below:
SELECT
dkh.STATISTIC_DATE AS 'Date'
,week(dkh.STATISTIC_DATE,4) as 'Week'
,month(dkh.STATISTIC_DATE) as 'Month'
,year(dkh.STATISTIC_DATE) as 'Year'
,dkh.SITE AS 'Site ID Short'
,aep.LOC_DESCR as 'Site Name'
,dkh.EMPLOYEE_ID AS 'Employee ID'
,count(distinct dkh.EMPLOYEE_ID) AS 'Distinct Employee ID'
,aep.NAME AS 'Employee Name'
,aep.BUSINESS_TITLE AS 'Business_Ttile'
,aep.SPRVSR_NAME AS 'Manager'
,SUBSTR(aep.DEPTID,1,4) AS 'Cost_Center'
,dkh.PAY_CODE
,dkh.PAY_CODE_SHORT
,dkh.HOURS
FROM metrics.DAT_KRONOS_HOURS dkh
JOIN metrics.EMPLOYEES_PUBLIC aep
ON aep.SNAPSHOT_DATE = SUBDATE(dkh.STATISTIC_DATE, DAYOFWEEK(dkh.STATISTIC_DATE) + 1)
AND aep.EMPLID = dkh.EMPLOYEE_ID
WHERE dkh.STATISTIC_DATE BETWEEN adddate(now(), interval -1 year) AND DATE(now())
group by dkh.SITE, SUBSTR(aep.DEPTID,1,4), week(dkh.STATISTIC_DATE,4), dkh.STATISTIC_DATE, dkh.EMPLOYEE_ID
The order you use in group by doesn't matter. Each unique combination of the values gets a group of its own. Selecting columns you don't group by gives you somewhat arbitrary results; you'd probably want to use some aggregation function on them, such as SUM to get the group total.
Grouping by values you derive from other values that you already use in group by, like below, isn't very useful.
week(dkh.STATISTIC_DATE,4), dkh.STATISTIC_DATE
If two rows have different weeks, they'll also have different dates, right?

MySQL Week Function Unexpected Results

I am querying a database of hour entries and summing up by company and by week. I understand that MySQL's week function is based on a calendar week. That being said, I'm getting some unexpected grouping results. Perhaps you sharp-eyed folks can lend a hand:
SELECT * FROM (
SELECT
tms.date,
SUM( IF( tms.skf_group = "HP Group", tms.hours, 0000.00 )) as HPHours,
SUM( IF( tms.skf_group = "SKF Canada", tms.hours, 000.00 )) as SKFHours
FROM time_management_system tms
WHERE date >= "2012-01-01"
AND date <= "2012-05-11"
AND tms.skf_group IN ( "HP Group", "SKF Canada" )
GROUP BY WEEK( tms.date, 7 )
# ORDER BY tms.date DESC
# LIMIT 7
) AS T1
ORDER BY date ASC
My results are as follows: (Occasionally we don't have entries on a Sunday for example. Do null values matter?)
('date'=>'2012-01-01','HPHours'=>'0.00','SKFHours'=>'2.50'),
('date'=>'2012-01-02','HPHours'=>'97.00','SKFHours'=>'78.75'),
('date'=>'2012-01-09','HPHours'=>'86.50','SKFHours'=>'100.00'),
('date'=>'2012-01-16','HPHours'=>'68.00','SKFHours'=>'96.25'),
('date'=>'2012-01-24','HPHours'=>'39.00','SKFHours'=>'99.50'),
('date'=>'2012-02-05','HPHours'=>'3.00','SKFHours'=>'93.00'),
('date'=>'2012-02-06','HPHours'=>'12.00','SKFHours'=>'122.50'),
('date'=>'2012-02-13','HPHours'=>'64.75','SKFHours'=>'117.50'),
('date'=>'2012-02-21','HPHours'=>'64.50','SKFHours'=>'93.00'),
('date'=>'2012-03-02','HPHours'=>'45.50','SKFHours'=>'143.25'),
('date'=>'2012-03-05','HPHours'=>'62.00','SKFHours'=>'136.75'),
('date'=>'2012-03-12','HPHours'=>'54.25','SKFHours'=>'133.00'),
('date'=>'2012-03-19','HPHours'=>'77.75','SKFHours'=>'130.75'),
('date'=>'2012-03-26','HPHours'=>'61.00','SKFHours'=>'147.00'),
('date'=>'2012-04-02','HPHours'=>'86.75','SKFHours'=>'96.75'),
('date'=>'2012-04-09','HPHours'=>'84.25','SKFHours'=>'120.50'),
('date'=>'2012-04-16','HPHours'=>'90.00','SKFHours'=>'127.25'),
('date'=>'2012-04-23','HPHours'=>'103.25','SKFHours'=>'89.50'),
('date'=>'2012-05-02','HPHours'=>'72.50','SKFHours'=>'143.75'),
('date'=>'2012-05-07','HPHours'=>'68.25','SKFHours'=>'119.00')
January 2nd is the first Monday, hence Jan 1st is only one day. I would expect the output to be consecutive Mondays (Monday Jan 2, 9, 16, 23, 30, etc)? The unexpected week groupings below continue throughout the results. Any ideas?
Thanks very much!
It's not clear what selecting tms.date even means when you're grouping by some function on tms.date. My guess is that it means "the date value from any source row corresponding to this group". At that point, the output is entirely reasonable.
Given that any given group can have seven dates within it, what date do you want to get in the results?
EDIT: This behaviour is actually documented in "GROUP BY and HAVING with Hidden Columns":
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause.
...
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.
The tms.date column isn't part of the GROUP BY clause - only a function operating on tms.date is part of the GROUP BY clause, so I believe the text above applies to the way that you're selecting tms.date: you're getting any date within that week.
If you want the earliest date, you might try
SELECT MIN(tms.date), ...
That's assuming that MIN works with date/time fields, of course. I can't easily tell from the documentation.
Question is not clear for me but I guess you don't want to group by week. Because week gives week of year. which is 19th week today.
I think you want to group by Weekday like GROUP BY WEEKday(tms.date)