I got a skill test for a quick mysql query. I am given the tables:
Orders OrderItems
----------------------------------------
id id
date order_id(Orders.id)
shipping_amount product_id
order_status price
customer_id quantity
I need to show Orders id and totals (including shipping amount) and records prior to June 1, 2003.
output should be...
| OrderID | OrderTotal |
+-----------+------------+
| 13230 | $55.00 |
| 54455 | $40.00 |
| 59694 | $33.04 |
| 39495 | $21.05 |
The hint is to use Group by or subselect. I have the following statement so far but not sure what to do next.
Select id AS OrderId,***(not sure what to do here)
from Orders join OrderItems on Orders.id=OrderItems.id
I don't have access to a mysql database to test, but I would imagine it looks something like this:
select
o.id OrderID,
(select sum(oi.price * oi.quantity) from order_items oi where oi.order_id = o.id) + o.shipping_amount OrderTotal
from
orders o
where
o.date < str_to_date('2003-06-01', '%Y-%m-%d');
I'd say it must look like this:
SELECT O.ID as OrderID, SUM(OI.price * OI.quantity) AS OrderTotal
FROM Orders O
INNER JOIN OrderItems OI ON O.id = OI.order_Id
WHERE date < '2003-06-01'
GROUP BY O.id
ORDER BY SUM(price * quantity) DESC
Not sure how to format dates in MySQL though or if you can order by an agregate function in this version but I'm pretty sure this is a good start.
Related
I am stuck in a problem since long.
I have a table for orders of customers, I want to get 4 types of results like
1st: All orders with status=place
then 2nd: All orders with status=place and customer is new (no previous record in order table of this customer),
then 3rd: All orders with status=place and customer have at least 1 order delivered and never returned previous order ,
then 4th: All orders with status=place and customer have atleast 1 order with status=returned
Query for 1st step is working fine, but i got no idea to get other results.I know its like an assignment but i need help.
MY Try for 1st step
SELECT o.order_id, o.customer_id, o.order_status_id,
FROM `order` o
WHERE (o.order_status_id = '1'
AND o.payment_code <> 'paytabs'
AND o.payment_code <> 'pp_express')
ORDER BY o.order_id DESC
This give me perfect result for step one.I am using OpenCart 2.2.0.0
Database Structure
|order_id |status | payment_code |customer_id |
|---------|-------|--------------|------------|
| 10 | place | cod | 5 |
| 11 | delvr | cod | 4 |
| 12 | return| pp_express | 5 |
| 13 |process| paytabs | 2 |
Any help or suggestion will be appreciated.
Ask me for anything you need more.
Not sure to understand your DB structure, but I will try...
Ad 2:
SELECT o.order_id, o.customer_id, o.order_status_id,
FROM `order` o
WHERE (o.order_status_id = '1'
AND o.payment_code <> 'paytabs'
AND o.payment_code <> 'pp_express')
AND o.customer_id NOT IN (SELECT o2.customer_id from order o2 WHERE o2.order_id != o.order_id AND o2.customer_id = o.customer_id)
ORDER BY o.order_id DESC
Accordingly, ad 4:
SELECT o.order_id, o.customer_id, o.order_status_id,
FROM `order` o
WHERE (o.order_status_id = '1'
AND o.payment_code <> 'paytabs'
AND o.payment_code <> 'pp_express')
AND o.customer_id IN (SELECT o2.customer_id from order o2 WHERE o2.order_status = 'returned')
ORDER BY o.order_id DESC
Now for 3:
SELECT o.order_id, o.customer_id, o.order_status_id,
FROM `order` o
WHERE (o.order_status_id = '...?')
AND o.customer_id NOT IN (SELECT o2.customer_id from order o2 WHERE o2.order_status = 'returned')
AND o.customer_id IN (SELECT o3.customer_id from order o3 WHERE o3.order_status = 'delivered')
ORDER BY o.order_id DESC
BTW: I strongly recommend to rename table "order" since "order" is an SQL keyword.
I think you should use Union when you want to do that with one query.
Other ways, when same customer meets 2 contidions, then you will only see one.
https://www.w3schools.com/sql/sql_union.asp
For the 2nd query : you can just add an AND clause to your SQL :
AND user_id = 0
Assuming a new order is inserted with user_id = 0 if this is a new user
queries:
the queries are as per your question u asked and you orders table structure(i am considering that you have not created any column like created_at and updated_at).
select * from orders where status = 'place';
select orders.order_id ,orders.customer_id from orders where status = 'place' GROUP BY order_id, customer_id HAVING COUNT(customer_id) = 1;
select a.order_id, a.customer_id from orders a where a.status in (select b.status from orders b where a.order_id = b.order_id and status <> 'return') and a.status = 'place' GROUP BY a.order_id, a.customer_id HAVING COUNT(a.customer_id) >= 1;
select a.order_id, a.customer_id from orders a where a.status in (select b.status from orders b where a.order_id = b.order_id and status = 'return') and a.status = 'place' GROUP BY a.order_id, a.customer_id HAVING COUNT(a.customer_id) >= 1
I want to calculate total products in cart for one user by summing values for each product in cart.
I'm using this query :
SELECT *, SUM(quantity) OVER (PARTITION BY product_id ORDER BY id) AS TotalProducts
FROM cart WHERE user_id ='$user_id';
Getting error:
SQL syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near '(PARTITION BY product_id
ORDER BY id)
EDIT with DB schema
id | product_id | quantity | user_id
1 | 37 | 2 | 23847
2 | 70 | 2 | 23847
I can't see what I'm doing wrong?
I'm not familiar with the MariaDB syntax, and you didn't show your schema, but here's my shot at an answer:
SELECT c.*,
SUM(c.quantity) as `TotalProducts`
FROM cart c
WHERE c.user_id = '$user_id'
GROUP BY c.user_id
Or, if you want a total per product, you could use:
SELECT c.*,
SUM(c.quantity) as `TotalProducts`
FROM cart c
WHERE c.user_id = '$user_id'
GROUP BY c.user_id, c.product_id
In MySQL, you can use a correlated subquery:
SELECT c.*,
(SELECT SUM(c2.quantity)
FROM cart c2
WHERE c2.user_id = c.user_id AND
c2.product_id = c.product_id AND
c2.id <= c.id
) as TotalProducts
FROM cart c
WHERE user_id = '$user_id';
Okay I have a table 3 Tables (Orders, Order_details, Products)
Orders
id | order_date
1 | March-01-13
2 | March-02-13
3 | April-01-13
4 | May-01-13
5 | June-01-13
and so on.....
Order_Details
id | order_id | product_id | total_price
1 1 1 100 /*mouse*/
2 1 3 200 /*monitor*/
3 2 2 50 /*keyboar*/
4 2 3 200 /*monitor*/
and so on....
Products
id | title
1 mouse
2 keyboard
3 monitor
and so on...
And here is my SQL Query that giving unexpected output
SELECT title, SUM(total_price) as total_price, orders.order_date as date
FROM products
LEFT JOIN order_details
ON order_details.product_id=products.id
LEFT JOIN orders
ON orders.id=order_details.order_id
WHERE title='monitor' /*this is just a try, prod_id should be the one*/
GROUP BY MONTH(date)
ORDER BY total_price DESC LIMIT 10
What I want to get is the total_price of product_id in all months
Expected Output
title | total_price | date
monitor 400 March
When using a GROUP BY, all of the fields in the SELECT list need to either be aggregated, or be part of the GROUP BY. So try adding the 'title' to the group by, and adding the MONTH function to the order_date in the SELECT list as follows:
SELECT title, SUM(total_price) as total_price, MONTH(orders.order_date) as date
FROM products
LEFT JOIN order_details ON order_details.product_id=products.id
LEFT JOIN orders ON orders.id=order_details.order_id
WHERE title='monitor'
GROUP BY title, date
ORDER BY total_price DESC LIMIT 10
This will get the total_price for each product for each month.
Do you want something like this?
SELECT p.title, SUM(total_price) as total_price
FROM products p LEFT JOIN
order_details od
ON od.product_id = p.id LEFT JOIN
orders o
ON o.id = od.order_id
GROUP BY p.title
ORDER BY total_price DESC
LIMIT 10;
I don't see why your sample output would have a month in it.
So i have two tables:
order_product
--------------------------------------------------
| ProductID | Quantity
--------------------------------------------------
products
-------------------------------------------------------------
| ProductID | productname | Desc | Price | Stock | Image
------------------------------------------------------------
and i need to get all of the same product ID, show their quantity then times that by their price and show the grand total of all.
My problem is i'm trying to show a checkout page which shows everything in a list, but how do i combine the two tables? Also, there are no foreign keys for the first table.
I need this in an sql statement as well preferably, like:
$sql = 'SELECT...'
Would this work?
$sql = "SELECT * FROM order_products
UNION
SELECT * FROM products"
If so, how do i know which row is which?
My desired output is all entries, now looking like this:
ProductID | Quantity | Productname | Desc | Price | Stock | Image
You need a classical JOIN clause:
SELECT *
FROM products
LEFT JOIN order_products on products.ProductId = order_products.ProductId
Not sure exactly what's the output you wish to get is but you should use something like this
SELECT o.ProductID, o.Quantity, p.Price, o.Quantity * p.Price
FROM order_product o
LEFT JOIN products p ON o.ProductID = p.ProductID
My problem is i'm trying to show a checkout page which shows
everything in a list, but how do i combine the two tables?
You need to simply use mysql JOIN to show cart items.
Your table data should be like as i added in demo.
See SQL Fiddle Demo
SELECT
o.id 'orderId',
o.ProductID 'pid',
SUM(o.Quantity) 'qty',
p.productname 'product',
p.`Price` 'price'
FROM
order_product o
INNER JOIN products p
ON p.`ProductID` = o.`ProductID`
Edit Required output
My desired output is all entries, now looking like this:
ProductID | Quantity | Productname | Desc | Price | Stock | Image
Modify above query's SELECT part SELECT tablename.your_column .....
Use inner join.
Select * from order_products op INNER JOIN products p ON p.ProductID = op.ProductID;
w.r.t. your need, the above query needs to be modified to:-
"SELECT *,
SUM(op.quantity * p.price) AS grandTotal
FROM order_products op
INNER JOIN PRODUCT p ON p.ProductID = op.ProductID WHERE p.ProductID =".$prodId(your php variable of product id);
select table1.ProductID
, table1.Quantity
, table2.Productname
, table2.Desc
, table2.Price
, table2.Stock
, table2.Image
FROM table1
JOIN table2 ON table1.productid=table2.productid
I have two tables, tbl_customers and tbl_transactions, where the fields of them are as follows:
**tbl_customer:**
c_id | c_name | age | Slab | gender | occupation | married | priority | ratings | contact | email | dob | anniversary
**tbl_transaction**
t_id | c_id | d_id | f_id | date_time | bill | member
The table tbl_transaction is a global table containing the transactions of all departments, differentiated by d_id.
Now I want to run a query that fetches c_id, total visits(means no of rows a c_id apppears in tbl_transaction), total revenue(means SUM(bill) of a particular c_id in) and the respective priority and ratings as it is in tbl_customer.
The query I was trying is :
Select c_id,
COUNT(cid) as tot_visit,
SUM(bill) as tot_revenue, priority, ratings
From tbl_customer c
inner join tbl_transaction t on c.c_id=t.c_id
Where $r_id='r1' AND $c_id='".$cid."'
group by c_id
So basicaly I want to display the total visits and revenue of each customer in customer table, but not sure what is the right way to do it.
Any help would be appreciated.
This is the error I am getting in SQL Engine
According to your error there are fields in both tables that have same name in your tables you need to give the table alias for the field, also when you are filtering on only one group then there is no need to use group by because you are using AND c.c_id='".$cid."' for a single group
Select c.c_id,
COUNT(c.cid) as tot_visit,
SUM(t.bill) as tot_revenue, c.priority, c.ratings
From tbl_customer c
inner join tbl_transaction t on c.c_id=t.c_id
Where $r_id='r1' AND c.c_id='".$cid."'
group by c.c_id
In general the query is fine. I would replace inner join with outer to process customers cho don't have transactions
Select c_id, COUNT(cid) as tot_visit, SUM(bill) as tot_revenue,
priority, ratings
From tbl_customer c LEFT JOIN tbl_transaction t on c.c_id=t.c_id
Where $r_id='r1' AND $c_id='".$cid."'
group by c_id