SQL query for Calculating Total No. of Orders per Day? - php

Can anyone post a SQL query for Calculating Total No. of Orders per Day?
Here are the Columns along with their data in my Database.
order_id order_placed_date order_total
- 1 12/30/2008 12:06:24 AM 2499.99
- 2 2/3/2009 1:57:17 AM 199.99
- 3 2/3/2009 1:58:27 AM 449.99
- 4 5/3/2009 1:58:48 AM 299.99
- 5 6/3/2009 2:00:31 AM 359.94
- 6 6/3/2009 2:01:47 AM 279.97
- 7 6/3/2009 2:02:31 AM 1359.94
- 9 7/1/2009 2:21:18 PM 5099.98
- 10 7/1/2009 2:21:36 PM 2621.97
- 11 7/2/2009 2:22:18 PM 2169.95
- 12 7/3/2009 2:23:29 PM 2249.95
- 13 7/4/2009 2:24:24 PM 5509.95
- 14 7/5/2009 12:15:17 AM 449.99
- 15 7/5/2009 12:18:08 AM 2299.99
- 16 7/5/2009 12:18:28 AM 3999.99
- 17 7/5/2009 12:18:45 AM 1939.99
- 18 7/5/2009 11:58:07 PM 39.99
- 19 7/6/2009 12:00:42 AM 1899.99
- 20 7/6/2009 12:01:00 AM 3999.99
- 21 7/7/2009 12:06:38 AM 199.99
- 22 7/7/2009 12:08:31 AM 1143.97
- 23 7/7/2009 12:09:13 AM 449.99
- 26 7/15/2009 1:30:03 PM 5469
- 27 7/15/2009 2:14:24 PM 329.97
- 28 7/15/2009 6:18:47 PM 5469
- 29 7/15/2009 10:17:36 PM 39.99
For e.g. there are 2 orders in the month of Febuary 2009
- 2 2/3/2009 1:57:17 AM 199.99
- 3 2/3/2009 1:58:27 AM 449.99
I need a sql query which would calculate and show the total amount per day. So for 3rd of Feb 2009, the total would be 699.98
I need to display Total Order Amount per day in a Chart
If it would be easier to do it with PHP, do mention it as well.
UPDATE:
I would like to clarify that I needed the Total Amount Per Day in the Present Month. I forgot to mention that in my initial question.
So i udpated Peter's query to get Total No. of Orders + Total Amount per Day in this Month.
Please, let me know if it needs any correction or is there a better and shorter way of doing it.
SELECT date(order_placed_date), COUNT(order_id) AS num_orders, SUM(order_total) AS daily_total
FROM orders
WHERE order_placed_date>=date_sub(current_date, INTERVAL 31 DAY)
GROUP BY date(order_placed_date)

MySQL's date() function will return a DATEIME or TIMESTAMP value without any hour/minute/second info - which means you reduce the accuracy to the day of the value.
So all you need to do is group by that and then add your aggregate functions to the right columns.
SELECT date(order_placed_date)
, COUNT(id) AS num_orders
, SUM(order_total) AS daily_total
FROM [Table]
GROUP BY date(order_placed_date)

SELECT date(order_placed_date)
, COUNT(id) AS num_orders
, SUM(order_total) AS daily_total
FROM orders
GROUP BY 1
Just copied Peter's answer but altered it so it will work. Plus shortcuted the group by.

A group by is your friend here. It can aggregate on grouped rows. An example query would be:
SELECT order_placed_date, SUM(order_total)
FROM orders
GROUP BY order_placed_date
Of course, in your example you'd probably want to extract just the day/month/year part using the DATE() function, and group by that.

select YEAR(datename(year,ORDER_DATE)) as YEARS,
count(ORDER_nO) as [NO(ORDER)]
from ProductOrder
group by YEAR(datename(year,ORDER_DATE))

I don't know what it is in MySQL but in MSSQL it would be this,
select
datepart(yyyy, order_placed_date),
datepart(mm, order_placed_date),
datepart(dd, order_placed_date),
sum(order_total)
from orders
group by datepart(yyyy, order_placed_date), datepart(mm, order_placed_date), datepart (dd, order_placed_date)

Related

How can i get all months With between two dates

i have this query that get all regsiterd data between this two dates
SELECT date as date_month, status FROM tbl_reports WHERE status != 0 AND (date BETWEEN '2017-01-01' AND '2017-12-31') GROUP BY MONTH(date)
result
date_month
2017-04-19
2017-05-24
2017-06-26
2017-07-01
but how i can get the result even if there is no regsitered input in the other months
want result
Date_month
2017-01-01
2017-02-01
2017-03-01 - it will give this value if there is no such data in this month
2017-04-19 - i will get the input date from database
'' '' ''
2017-12-31
is it possible ? or i need some php code to manipulate this data?
thank you in advance for my answering my question.. :)
Create an extra table, named datehelper. Provide it with 2 columns: year and month. And fill those with year: 2017 until 2027 and 1 / 12 for the months.
SELECT
datehelper.year,
datehelper.month,
r.status
FROM datehelper
LEFT JOIN tbl_reports r ON MONTH(r.date) = datehelper.month
AND YEAR(r.date) = datehelper.year AND status != 0
WHERE (datehelper.year = '2017')
ORDER BY datehelper.year, datehelper.month
I see you would get duplicates on the left joined part if there are more records there in a certain month.
What status would you expect? Let's think there are records with status 0 (excluded) status = 1, and status = 2
datehelper:
year month
2017 1
2017 2
2017 3
2017 4
...
2017 11
2017 12
2018 1
...

MySQL Two Queries Producing One Value

I need to make a query that selects from two different tables. Basically, I only want to select the rows from the dates table that have no pending orders in the orders table.
For example, the dates table has the values of July 1, July 2 and July 3. July 2 has orders with the status = PEN in the orders table so the table will only show July 1 and July 3.
Query 1 for dates:
$sql = "SELECT * FROM dates WHERE DATEDIFF(CURDATE(), date) >= 30 AND `30day`='No'";
I have yet to build a query for the orders table as I am sure this needs to be integrated into one query together, and I am not sure what to do.
I know you can do two SELECT queries in one, and I am aware of how to do this, but I am unsure of how to cause the second SELECT query to be affected by the first SELECT query.
dates database has columns id date closed 30day 60day
orders database has columns id date order status
I need this query to flag any orders with the statuses PEN BO FBO.
Thank you in advance!
Sample Data:
dates table:
Date - 30-day Value
July 1 - No
July 2 - No
July 3 - No
orders table:
Date - Orders - Status
July 1 - 7123456 - PEN
July 1 - 7123457 - SHI
July 1 - 7123487 - SHI
July 2 - 7256789 - SHI
July 2 - 7256790 - SHI
July 2 - 7256791 - SHI
July 3 - 7215368 - SHI
July 3 - 7125369 - SHI
July 3 - 7659876 - BO
July 4 - 7569235 - FBO
July 4 - 7986585 - FBO
Expected Result:
Date
July 2
July 3
Omitted Dates:
Date - Reason
July 1 - because there is an open order
July 4 - because there is an open order
I don't want an omitted table - just wanted to show what wouldn't show up.
could be this what you are looking for (i don't know your schema so for the join i have used a column named key
$sql = "SELECT *
FROM dates
LEFT JOIN orders on (dates.date = orders.date and orders.status not in ('PEN','BO', 'FBO'))
WHERE DATEDIFF(CURDATE(), dates.date) >= 30
AND `30day`='No'";
otherwise if you need that status is not PEN, BO and FBO then you can
..
$sql = "SELECT *
FROM dates
LEFT JOIN orders ON dates.date = orders.date
WHERE DATEDIFF(CURDATE(), dates.date) >= 30
AND `30day`='No'
AND orders.status NOT IN ('PEN','BO', 'FBO' ) ";
..
$sql = "SELECT *
FROM dates
INNER JOIN orders ON dates.date = orders.date
WHERE DATEDIFF(CURDATE(), dates.date) >= 30
AND `30day`='No'
AND orders.status IN ('PEN','BO', 'FBO' ) ";
based on the sample provided this should return the rows you need
$sql = " SELECT *
FROM dates
WHERE DATEDIFF(CURDATE(), date) >= 30
AND `30day`='No'
AND date not in (
select date
from orders
where order.status IN ('PEN','BO', 'FBO' )
) ";

How can I take the ids of the registrations with the highest temperature of each day (on a specified period of time)?

Considering I have more than 30 registers/day for that temperature.
Name of the table: 'temperatures'
Colomn name: 'TempA'
I want one registration for each day, for example:
date: 2015-12-10 12:02 id: 2341 tempa: 54 (which is the highest on that day)
date: 2015-12-09 15:04 id 1923 tempa: 32 (which is the highest on that day)
and so on....
you can use max and group by
select max(TempA) from your_table group by day_column
select id from temperatures where TempA=(select max(TempA) from temperatures )

SQL for grouping by timeframe with empty frames

My goal is it to create a SQL-Query that counts all items in a certain time frame (e.g. 5min)
That's my code so far:
SELECT FROM_UNIXTIME(FLOOR(timestamp_stop/5*60)*(5*60), '%h:%i') AS timekey, timestamp_stop, count(item) AS performance
FROM task
WHERE done = 1
GROUP BY timekey
ORDER BY timestamp_stop ASC
That works great, but doesn't include time frames in which there aren't any records in the database.
I would like to also get these 0-count-ones, up to the current time.
Currently I have no simple/elegant solution in my mind. Any ideas?
Some little post processing in php would also be possible.
As Gordon mentioned, you probably want a secondary table as a basis for ALL 5-minute intervals. I have done similar with a query to self-build using MySQL variables.
select
YourTable.WhateverFields
from
( select
#startTime RangeStart,
#startTime := date_add( #startTime, interval 5 MINUTE ) RangeEnd
from
( select #startTime := '2014-10-20' ) sqlvars,
AnyTableThatHasAsManyDaysYouExpectToReport
limit
12 * numberOfHoursYouNeed * numberOfDaysYouNeed ) DynamicTimeRange
LEFT JOIN YourTable
on YourTable.DateTimeField >= DynamicTimeRange.RangeStart
AND YourTable.DateTimeField < DynamicTimeRange.RangeEnd
So, in this example, the innermost declars a variable "startTime" to Oct 20, 2014 which defaults to 12:00:00. Then the one out from that creates a result set of two columns for a RangeStart and RangeEnd and might look something like...
RangeStart RangeEnd
2014-10-20 00:00 2014-10-20 00:05
2014-10-20 05:00 2014-10-20 00:10
2014-10-20 10:00 2014-10-20 00:15
2014-10-20 05:00 2014-10-20 00:20
2014-10-20 20:00 2014-10-20 00:25
The table reference "AnyTableThatHasAsManyDaysYouExpectToReport" is just that... any table in your database that has at least as many records as you would need to generate your 5-minute intervals for however many hours and days. If you need 1 day worth = 12 records * 5 minutes = 1 hour * 24 hrs = 24*12 = 288 records needed. If you wanted a week, then so be it... multiply that by 7 so my sample just has place-holders to help clarify the intent...
But with the LEFT JOIN, you get all the intervals...
If there are such time frame, but the where clause filters out the records, you can do:
SELECT FROM_UNIXTIME(FLOOR(timestamp_stop/5*60)*(5*60), '%h:%i') AS timekey,
timestamp_stop,
sum(item is not null and done = 1) AS performance
FROM task
GROUP BY timekey
ORDER BY timestamp_stop ASC;
If you still have gaps, then you need to generate a table (or subquery) containing the list of the time frames that you want and use left join.
EDIT:
A subquery is not pleasant. You have to list all the time values. Something like:
SELECT q.timekey, t.timestamp_stop, coalesce(t.performance, 0) as performance
FROM (SELECT '00:00' as timekey UNION ALL
SELECT '00:05' UNION ALL
. . .
) q LEFT JOIN
(SELECT FROM_UNIXTIME(FLOOR(timestamp_stop/5*60)*(5*60), '%h:%i') AS timekey,
timestamp_stop,
COUNT(item) AS performance
FROM task
WHERE done = 1
GROUP BY timekey
) t
ON t.timekey = q.timekey
ORDER BY timestamp_stop ASC;

fetch daily customer flow data

I am trying to fetch daily customer flow from table 'tbl_transaction' using the following query:
SELECT DAY(date_time) AS date, SUM(members) AS customers FROM tbl_transaction WHERE MONTH(date_time)='.$mon.' GROUP BY "date_time"
But it is generating this dataset which is not grouped according to date:
date | customers
11 3
12 2
13 1
14 2
14 3
15 7
16 4
17 3
17 2
17 7
17 2
18 5
18 5
18 4
19 2
How to show the dates and no of customers as on particular date.
Your query should look like
SELECT DAY(date_time) AS date,
SUM(members) AS customers
FROM tbl_transaction
WHERE MONTH(date_time)='03' GROUP BY DATE(date_time)
Since date_time is in Y-m-d H:i:s so doing Group by date_time will return all the rows.
Also if you do Group By date which is obtained as DAY(date_time) AS date yield wrong result.
DAY('2014-01-01') = 1
DAY('2014-02-01') = 1
So it will sum up the result for days irrespective of actual date.

Categories