Thank you for looking at my question.
I am trying to sum the subtotal column and group by datetime via mysql. I have to join two tables, prior to the sum.
My first table, Payments, contains the following data:
ID | User_ID | Order_ID | Subtotal | Tax | Tip | Discount | Total | Payment_Method | Payment_Collected
12 | 123 | 76 | 10.99 | 0.99| 1 | 0.00 | 12.98 | Cash | 1
My second table, Order, contains the following data:
ID | User_ID | Address_ID | orderplaced_ts | order_status
76 | 23 | 123 | 2015-02-26 12:23:41 |
The query that I tried to run is as follows:
select `order`.orderplaced_ts, SUM(`payments`.subtotal) as Subtotal
from `payments`
join `order` on `order`.id=`payments`.order_id
where `order`.order_status != "Cancelled"
and `payments`.payment_collected = 1
group by `order`.orderplaced_ts
What I'm trying to achieve is to get all the sum of all subtotals and grouped by the same datetime. Sample output would be:
orderplaced_ts | Subtotal
2015-02-20 | 123.12
2015-02-21 | 223.12
2015-02-22 | 124.25
2015-02-23 | 247.23
2015-02-24 | 623.50
My current query output is:
orderplaced_ts | Subtotal
2015-02-20 05:56:23 | 123.12
2015-02-20 06:36:23 | 123.12
2015-02-20 06:38:23 | 123.12
Can someone please point me in the right direction of why my query isn't giving me the desired output?
You need to use a formatted date to get rid of the time.
I think this would do what you want (not tested):
select date_format(`order`.orderplaced_ts,"%Y-%m-%d"), SUM(`payments`.subtotal) as Subtotal
from `payments`
join `order` on `order`.id=`payments`.order_id
where `order`.order_status != "Cancelled"
and `payments`.payment_collected = 1
group by date_format(`order`.orderplaced_ts,"%Y-%m-%d")
Related
I have the table "Tcustomer":
+--------------+----------+---------+------------------+---------------+
| CustomerName | Product | Country | Submitted_apps | Finished_apps |
+--------------+----------+---------+------------------+---------------+
| Customer 1 | book1 | CZ | 2020-11-06 | 2020-11-06 |
| Customer 2 | book1 | SK | 2020-11-06 | 2020-11-07 |
| Customer 3 | book2 | CZ | 2020-11-06 | null |
+--------------+----------+---------+------------------+---------------+
Now, I need to have one output that will say to me, how many submitted_apps was in each day, how many finished_apps was in each day per the product and the Country.
So in the output, something like this:
+----------+---------+----------+------------------+---------------+
| Product | Country | Date | Submitted_apps | Finished_apps |
+----------+---------+----------+------------------+---------------+
| book1 | CZ |2020-11-06| 1 | 1 |
| book2 | CZ |2020-11-06| 1 | 0 |
| book1 | SK |2020-11-06| 1 | 0 |
| book1 | SK |2020-11-07| 0 | 1 |
+----------+---------+----------+------------------+---------------+
I did this, but it summarize only the date "submitted_apps". If I add also "finished_apps" to the GROUP BY statement, I have a lot of rows with nulls there.
My SQL code is this:
SELECT
COUNT (Submitted_apps) AS number_submitted_per_day,
COUNT (Finished_apps) AS number_finished_per_day,
Submitted_apps AS date
WHERE Submitted_apps > 2020-01-01
GROUP BY product, country, submitted_apps
But this SQL query tells me now, how many submitted and finished applications for the books was only for the date mentioned in "submitted_apps". But I need number of Finished_apps to the date "Finished_apps" and number of Submitted_apps" to the date "Submitted_apps".
Can you please help me?
You can unpivot the data using union all and then aggregate:
select Product, Country, date, sum(submitted) as num_submitted,
sum(finished) as num_finished
from ((select Product, Country, Submitted_apps as date, 1 as submitted, 0 as finished
from Tcustomer
) union all
(select Product, Country, finished_apps as date, 0 as submitted, 1 as finished
from Tcustomer
)
) c
group by Product, Country, date;
I have a MySQL table named, "store_update_stock" to store purchase & issue of items. Order status column maintain the states, "purchase" or "issue" when need. Purchase quantity has denoted by plus values (eg:-10) & issue quantity has denoted by minus values (eg:- -2) in the table.
To get the purchase & issue summary I used the following query.
SELECT item_id, item_name, order_status, (CASE order_status
WHEN "issue" THEN store_update_stock_details.qty * (-1)
ELSE store_update_stock_details.qty
END) quantity FROM store_update_stock
And generated the expected output as follows :
+---------+-----------+--------------+----------+
| item_id | item_name | order_status | quantity |
+---------+-----------+--------------+----------+
| 1000 | A4 | purchase | 10 |
| 1001 | A3 | purchase | 5 |
| 1000 | A4 | issue | 2 |
| 1000 | A4 | issue | 3 |
| 1001 | A3 | purchase | 6 |
+---------+-----------+--------------+----------+
But I need to get further the balance of each items after performing purchases & issues by modifying the above query and get the output as follows :
+---------+-----------+---------+
| item_id | item_name | balance |
+---------+-----------+---------+
| 1000 | A4 | 5 |
| 1001 | A3 | 11 |
+---------+-----------+---------+
What can be done in my query to get the desired output. Can anyone helpme ?
It looks like all you might need is a simple aggregate sum and a group by:
select item_id, item_name, sum(quantity) as balance
from store_update_stock
group by item_id, item_name
maybe?
I want to sum every time and check with if condition. If condition matches I want the get the created date of the final matched row.
+------------+----------------------------------+------------+--------+
| id | EMAIL | created | Amt |
+------------+----------------------------------+------------+--------+
| 61 | abc#gmail.com | 1514909390 | 57.00 |
| 25 | xyz#gmail.com | 1515534837 | 360.00 |
| 36 | zccc#abv.com | 1515645391 | 240.00 |
| 22 | vv#aa.com | 1516419622 | 320.40 |
| 48 | aa#xyz.com | 1516706121 | 240.00 |
+------------+----------------------------------+------------+--------+
I try this query but I'm not getting the solution...
select
sum(a.amount) as amt,
if(sum(a.amount)>8000,slp.sal_time,0) as Amt_exceed_date
from employee a
join emp_user u
on a.cmp_id=u.user_id
left join emp_sal as slp
on slp.user_id=a.cmp_id
where
order by slp.sal_time;
Somewhat like row wise sum
select e.*,(
select sum(Amt)
from employee
where created <= e.created
) row_wise_sum
from employee e
having row_wise_sum < 800
order by e.created
desc limit 1
Demo
I have two tables, one that store product information and one that stores reviews for the products.
I am now trying to get the number of reviews submitted for the products between two dates but for some reason I get the same results regardless of the dates i put.
This is my query:
SELECT
productName,
COUNT(*) as `count`,
avg(rating) as `rating`
FROM `Reviews`
LEFT JOIN `Products` using(`productID`)
WHERE `date` BETWEEN '2015-07-20' AND '2015-07-30'
GROUP BY
`productName`
ORDER BY `count` DESC, `rating` DESC;
This returns:
+------------+---------------------+
| productName| count|rating |
+------------+------+--------------+
| productA | 23 | 4.3333333 |
| productB | 17 | 4.25 |
| productC | 10 | 3.5 |
+------------+---------------------+
Products table:
+---------+-------------+
|productID | productName|
+---------+-------------+
| 1 | productA |
| 2 | productB |
| 3 | productC |
+---------+-------------+
Reviews table
+---------+-----------+--------+---------------------+
|reviewID | productID | rating | date |
+---------+-----------+--------+---------------------+
| 1 | 1 | 4.5 | 2015-07-27 17:47:01|
| 2 | 1 | 3.5 | 2015-07-27 18:54:22|
| 3 | 3 | 2 | 2015-07-28 13:28:37|
| 4 | 1 | 5 | 2015-07-28 18:33:14|
| 5 | 2 | 1.5 | 2015-07-29 11:58:17|
| 6 | 2 | 3.5 | 2015-07-30 15:04:25|
| 7 | 2 | 2.5 | 2015-07-30 18:11:11|
| 8 | 1 | 3 | 2015-07-30 18:26:23|
| 9 | 1 | 3 | 2015-07-30 21:35:05|
| 10 | 1 | 4.5 | 2015-07-31 14:25:47|
| 11 | 3 | 0.5 | 2015-07-31 14:47:48|
+---------+-----------+--------+---------------------+
when I put two random dates that I do know for sure they not on the date column, I will still get the same results. Even when I want to retrieve records only on a certain day, I get the same results.
You should not use left join, because by doing so you retrieve all the data from one table. What you should use is something like :
select
productName,
count(*) as `count`,
avg(rating) as `rating`
from
products p,
reviews r
where
p.productID = r.productID
and `date` between '2015-07-20' and '2015-07-30'
group by productName
order by count desc, rating desc;
If the result, given your sample data, that you're looking for is:
| productName | count | rating |
|-------------|-------|--------|
| productA | 5 | 4 |
| productB | 3 | 3 |
| productC | 1 | 2 |
This is the count and average of reviews made on any date between 2015-07-20 and 2015-07-30 inclusive.
Then the there are two issues with your query. First, you need to change the join to a inner join instead of a left join, but more importantly you need to change the date condition as you are currently excluding reviews that fall on the last date on the range, but after midnight.
This happens because your between clause compares datetime values with date values so the comparison ends up being date between '2015-07-20 00:00:00' and '2015-07-30 00:00:00' which clearly excludes some dates at the end.
The fix is to either change the date condition so that the end is a day later:
where date >= '2015-07-20' and date < '2015-07-31'
or cast the date column to a date value, which will remove the time part:
where date(date) between '2015-07-20' and '2015-07-30'
Sample SQL Fiddle
You are using a LEFT JOIN between your reviews and your products tables. This will result in all the rows of reviews being shown with some rows having all product columns left empty.
You should use INNER JOIN, as this will filter only the wanted results.
(In the end I can only guess, since I don't even know which column belongs to which table ...)
The full query (very similar to Angelo Giannis's solution):
select
productName,
count(*) as `count`,
avg(rating) as `rating`
from
products INNER JOIN reviews USING(productId)
where date between '2015-07-20' and '2015-07-30'
group by productName
order by count desc, rating desc;
Here a fiddle with my and Angelo's solution (they both work).
I'm trying to do some report line chart graphs and find it easiest if I return one data row from my query for each column (date) of data that will appear in a line chart. The challenge is that I want more than one line.
Here is what I can do with a simplified example of data:
| DATE | SALES | LOCATION |
| 2012-01-07 | 500 | 1 |
| 2012-01-07 | 600 | 2 |
| 2012-01-14 | 700 | 1 |
| 2012-01-14 | 400 | 2 |
| 2012-01-21 | 450 | 1 |
| 2012-01-21 | 550 | 2 |
SELECT date, sum(sales) as SalesTotal1 FROM TABLE WHERE location = '1' group by date
Which returns:
| DATE | SalesTotal1 |
| 2012-01-07 | 500 |
| 2012-01-14 | 700 |
| 2012-01-21 | 450 |
That's fine if I just have one line in my graph but what I really want in more than one alias of the same column still grouped by date that would return this:
| DATE | SalesTotal1 | SalesTotal2 |
| 2012-01-07 | 500 | 600 |
| 2012-01-14 | 700 | 400 |
| 2012-01-21 | 450 | 550 |
Is this possible? Sub query? I've tried many things, thanks ~
You could do something like:
SELECT `date`,
SUM(IF(location=1,sales,0)) As SalesTotal1,
SUM(IF(location=2,sales,0)) As SalesTotal2
FROM my_table
GROUP BY `date`
You'd have to add in as many columns as there are locations though, and if you have many locations it would be annoying. Perhaps you could consider doing the re-arranging on the code side (if you have many, many locations)?
This is called a PIVOT table query which is not generally supported by MYSQL. However, if you know exactly the locations you can do it with a chain of sub-queries. If you don't know the exact locations you have to write a stored procedure that looks up the locations and builds a query string and then executes. Here's how to do two locations:
SELECT
date,
SalesTotal1,
SalesTotal2
FROM (
SELECT
date,
sum(sales) as SalesTotal1
FROM TABLE
WHERE location = '1'
group by date
) S1
INNER JOIN (
SELECT
date,
sum(sales) as SalesTotal2
FROM TABLE
WHERE location = '2'
group by date
) S2 ON S1.date=S2.date