SQL query to order by day, date and lead count - mysql

Trying to figure out how to pull data arranged by day, date and leads stats in the following format
Example output format
Day Date Leads
Today 2020/09/14 3
Yesterday 2020/09/13 64
Saturday 2020/09/12 18
Friday 2020/09/11 29
Thursday 2020/09/10 17
Wednesday 2020/09/09 94
A lead will is either a email or number
What SQL query can I use to get this
Example data
CREATE TABLE weektest(
date datetime,
lead VARCHAR(100)
);
INSERT INTO weektest(date, lead)
VALUES
(
'2020/09/04 10:36:51', 'number'
);
INSERT INTO weektest(date, lead)
VALUES
(
'2020/09/08 00:47:52', 'email'
);
INSERT INTO weektest(date, lead)
VALUES
(
'2020/09/11 03:03:41', ''
);

Do you just want aggregation?
select dayname(w.date) day, date(w.date) as date, count(*) cnt
from weektest w
group by date(w.date)
order by date(w.date)
I am not sure what you want to count: the above query gives you the number of rows per day. If you want the count of distinct lead values, then use count(distinct leads) instead of count(*).

Related

How do I SELECT a MySQL Table value that has not been updated on a given date?

I have a MySQL database named mydb in which I store daily share prices for
423 companies in a table named data. Table data has the following columns:
`epic`, `date`, `open`, `high`, `low`, `close`, `volume`
epic and date being primary key pairs.
I update the data table each day using a csv file which would normally have 423 rows
of data all having the same date. However, on some days prices may not available
for all 423 companies and data for a particular epic and date pair will
not be updated. In order to determine the missing pair I have resorted
to comparing a full list of epics against the incomplete list of epics using
two simple SELECT queries with different dates and then using a file comparator, thus
revealing the missing epic(s). This is not a very satisfactory solution and so far
I have not been able to construct a query that would identify any epics that
have not been updated for any particular day.
SELECT `epic`, `date` FROM `data`
WHERE `date` IN ('2019-05-07', '2019-05-08')
ORDER BY `epic`, `date`;
Produces pairs of values:
`epic` `date`
"3IN" "2019-05-07"
"3IN" "2019-05-08"
"888" "2019-05-07"
"888" "2019-05-08"
"AA." "2019-05-07"
"AAL" "2019-05-07"
"AAL" "2019-05-08"
Where in this case AA. has not been updated on 2019-05-08. The problem with this is that it is not easy to spot a value that is not a pair.
Any help with this problem would be greatly appreciated.
You could do a COUNT on epic, with a GROUP BY epic for items in that date range and see if you get any with a COUNT less than 2, then select from this result where UpdateCount is less than 2, forgive me if the syntax on the column names is not correct, I work in SQL Server, but the logic for the query should still work for you.
SELECT x.epic
FROM
(
SELECT COUNT(*) AS UpdateCount, epic
FROM data
WHERE date IN ('2019-05-07', '2019-05-08')
GROUP BY epic
) AS x
WHERE x.UpdateCount < 2
Assuming you only want to check the last date uploaded, the following will return every item not updated on 2019-05-08:
SELECT last_updated.epic, last_updated.date
FROM (
SELECT epic , max(`date`) AS date FROM `data`
GROUP BY 'epic'
) AS last_updated
WHERE 'date' <> '2019-05-08'
ORDER BY 'epic'
;
or for any upload date, the following will compare against the entire database, so you don't rely on '2019-08-07' having every epic row. I.e. if the epic has been in the database before then it will show if not updated:
SELECT d.epic, max(d.date)
FROM data as d
WHERE d.epic NOT IN (
SELECT d2.epic
FROM data as d2
WHERE d2.date = '2019-05-08'
)
GROUP BY d.epic
ORDER BY d.epic

How to return zero values if nothing was written in time interval?

I am using the Graph Reports for the select below. The MySQL database only has the active records in the database, so if no records are in the database from X hours till Y hours that select does not return anything. So in my case, I need that select return Paypal zero values as well even the no activity was in the database. And I do not understand how to use the UNION function or re-create select in order to get the zero values if nothing was recorded in the database in time interval. Could you please help?
select STR_TO_DATE ( DATE_FORMAT(`acctstarttime`,'%y-%m-%d %H'),'%y-%m-%d %H')
as '#date', count(*) as `Active Paid Accounts`
from radacct_history where `paymentmethod` = 'PayPal'
group by DATE_FORMAT(`#date`,'%y-%m-%d %H')
When I run the select the output is:
Current Output
But I need if there are no values between 2016-07-27 07:00:00 and 2016-07-28 11:00:00, then in every hour it should show zero active accounts Like that:
Needed output with no values every hour
I have created such select below , but it not put to every hour the zero value like i need. showing the big gap between the 12 Sep and 13 Sep anyway, but there should be the zero values every hour
(select STR_TO_DATE ( DATE_FORMAT(acctstarttime,'%y-%m-%d %H'),'%y-%m-%d %H')
as '#date', count(paymentmethod) as Active Paid Accounts
from radacct_history where paymentmethod <> 'PayPal'
group by DATE_FORMAT(#date,'%y-%m-%d %H'))
union ALL
(select STR_TO_DATE ( DATE_FORMAT(acctstarttime,'%y-%m-%d %H'),'%y-%m-%d %H')
as '#date', 0 as Active Paid Accounts
from radacct_history where paymentmethod <> 'PayPal'
group by DATE_FORMAT(#date,'%y-%m-%d %H')) ;
I guess, you want to return 0 if there is no matching rows in MySQL. Here is an example:
(SELECT Col1,Col2,Col3 FROM ExampleTable WHERE ID='1234')
UNION (SELECT 'Def Val' AS Col1,'none' AS Col2,'' AS Col3) LIMIT 1;
Updated the post: You are trying to retrieve data that aren't present in the table, I guess in reference to the output provided. So in this case, you have to maintain a date table to show the date that aren't in the table. Please refer to this and it's little bit tricky - SQL query that returns all dates not used in a table
You need an artificial table with all necessary time intervals. E.g. if you need daily data create a table and add all day dates e.g. start from 1970 till 2100.
Then you can use the table and LEFT JOIN your radacct_history. So for each desired interval you will have group item (group by should be based on the intervals table.

MySQL : Calculate business day difference between two dates column

My sql query returns back two columns, first column is "date created" and second column is "date updated", first column has a prior timestamp with respect to second column.
I need to add a third column which can display business day hrs (9:00am to 5:00pm) response i.e. if date created is 2012-01-04 09:00:20 and "dated updated" is 4:00pm same day then third column should display 7 hrs
If date created is 2012-01-04 16:00:20 (4:00pm) and "date updated" is 10:00m on 2012:01:05 (2nd Jan) then third column should display 2 hrs.
It should exclude Saturday and Sunday.
Can you please suggest appropriate SQL query for this.
As #Gordon Linoff commented, you need to create a table containing your business hours:
CREATE TABLE business_days (
start DATETIME NOT NULL,
end DATETIME NOT NULL
);
INSERT INTO `business_days`
(start, end)
VALUES
('2011-12-30 09:00', '2011-12-30 15:00'), -- short day
('2012-01-03 09:00', '2012-01-03 17:00'), -- 31st, 1st were Sat/Sun
('2012-01-04 09:00', '2012-01-04 17:00'), -- 2nd was a public holiday
('2012-01-05 09:00', '2012-01-05 17:00'),
-- etc.
Then you can do:
SELECT m.*,
SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(
LEAST(m.updated, b.end),
GREATEST(m.created, b.start)
))))
FROM my_table m JOIN business_days b
ON b.start < m.updated AND m.created < b.end
GROUP BY m.created, m.updated -- or some other key into my_table
See it on sqlfiddle.

how to sum different values of time type in sql table

my query :
SELECT (
`total_hours`
)
FROM work_details
WHERE `employee_id` = '28'
AND DATE
BETWEEN '2012-02-01'
AND '2012-02-01'
LIMIT 0 , 30
// Which takes total hours worked for a given employee in given date from database table work_details
result:
total_hours
02:27:29
00:13:56
03:03:49
00:00:03
00:30:20
01:04:13
//result shows the times an employee worked in a given date,I need to get the total of these values to find total working hour in a given date.
how to get sum of these values in a field???
if i use sum(total_hours) result would be
sum( total_hours )
67870
and that is not correct.I require it in time type itself.
And i have one more help needed, this query worked because i gave same date for the BETWEEN clause.
DATE
BETWEEN '2012-02-01'
AND '2012-02-01'
But i need to calculate total working hours of days in a given range , say
DATE
BETWEEN '2012-02-01'
AND '2012-02-29'
Since a given date has multiple total hours entry , i need get total hours for each distinct day.Help??
try this (taken from here):
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(`total_hours`))) ... -- rest of your query

Padding MYSQL data with missing dates when comparing year over year stats?

I have a table that tracks emails sent. It is pretty simple.
ID | DATETIME | E-MAIL | SUBJECT | MESSAGE
I have been collecting data for several years. Some days I don't have any entries in the table.
query1:
SELECT COUNT(ID) FROM emails
WHERE DATE(datetime) >= 'XXXX-XX-XX'
AND DATE(datetime) is <= 'ZZZZ-ZZ-ZZ'
GROUP BY DATE(datetime)
I then use a some php to get one year prior for both XXXX and YYYY and run the second query which is the same as the first...
query2:
SELECT COUNT(ID) from emails
WHERE DATE(datetime) >= 'XXXX-XX-XX'
AND DATE(datetime) is <= 'ZZZZ-ZZ-ZZ'
GROUP BY DATE(datetime)
I am using a charting package to compare how many emails I got for a date range and then I overlay how many emails I got for the same range only one year prior. This is two queries right now and I chart the results.
The issue is where mysql does not have any emails for 2011 for a day in question, but has a few in 2012 for the same day.
Combining the results and graphing them skews the results since I am missing a date and a 0 value for last year for that day, effectively making all my values no longer match up.
2011-03-01 10 2012-03-01 4
2011-03-02 4 2012-03-02 2
2011-03-03 6 2012-03-04 1 <---- see where the two queries
end up diverging? (I had nothing
logged for 2012-03-03 so naturally
it was not in the results.
Is there a way I can get mysql to output the data I need including dates where value appear in one year but not another OR if no values appear in either year (still need date and 0) so my chart works?
I cannot seem to figure out how to do this...
Thanks!
There are a few different ways to get the results for a contiguous set of dates. My favourite one is to create the full set that is required using a dummy table or an existing contiguous set of ids from an AI PK. Something like this -
SELECT '2011-01-01' + INTERVAL (id -1) DAY
FROM dummy
WHERE id BETWEEN 1 AND 365
This will return a full set of days for 2011 which can then be LEFT JOINed to your emails table to get the counts -
SELECT `dates`.`date`, COUNT(emails.id)
FROM (
SELECT '2011-01-01' + INTERVAL (id - 1) DAY AS `date`, '2011-01-01 23:59:59' + INTERVAL (id - 1) DAY AS `end_of_day`
FROM dummy
WHERE id BETWEEN 1 AND 365
) `dates`
LEFT JOIN emails
ON `emails`.`datetime` BETWEEN `dates`.`date` AND `dates`.`end_of_day`
GROUP BY `dates`.`date`
To populate your dummy / seq table you can insert the first ten values manually and then use INSERT ... SELECT to add the rest -
CREATE TABLE dummy (id INTEGER NOT NULL PRIMARY KEY);
INSERT INTO dummy VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SET #tmp := (SELECT MAX(id) FROM dummy) + 1;
INSERT INTO dummy
SELECT #tmp + id
FROM dummy;
You need to execute the SET query before each run of the INSERT ... SELECT query.