Need multiple rows with same value IN OPERATOR - sql

Suppose, order_id 4646, 4647 and 4648 are from same customer.
SELECT customer_id FROM orders WHERE order_id IN (4646, 4647, 4648)
Result:
customer_id
2589
2589
2589
Every customer has a gcm_registration_token.
SELECT gcm_registration_token FROM customer_details WHERE customer_id IN (2589, 2589, 2589)
Result:
gcm_registration_token
dyB_PhRHddU:APA91bGAbuxAIlHUmH2XYK0pWM3ON37O_mTF7g...
I want the second query to return 3 rows with same gcm_registration_token.
Expected result:
gcm_registration_token
dyB_PhRHddU:APA91bGAbuxAIlHUmH2XYK0pWM3ON37O_mTF7g...
dyB_PhRHddU:APA91bGAbuxAIlHUmH2XYK0pWM3ON37O_mTF7g...
dyB_PhRHddU:APA91bGAbuxAIlHUmH2XYK0pWM3ON37O_mTF7g...
A way around would be to fire query for each value. But, is it possible with single query.

Use JOIN like this:
SELECT c.gcm_registration_token
FROM orders o
JOIN customer_details c ON c.customer_id = o.customer_id
WHERE o.order_id IN (4646, 4647, 4648)

You can use INNER JOIN in following:
SELECT gcm_registration_token
FROM orders o
INNER JOIN customer_details d ON o.customer_id = d.customer_id
WHERE order_id IN (4646, 4647, 4648)

use INNER JOIN
SELECT `gcm_registration_token`
FROM `orders` o
INNER JOIN `customer_details` c ON `o`.`customer_id` = `c`.`customer_id`
WHERE `o`.`order_id` IN (4646, 4647, 4648)

select ord.customer_id as customerid , cd.gcm_registration_token from orders as ord
left join customer_details as cd on cd.customer_id = ord.customer_id
WHERE ord.order_id IN (4646, 4647, 4648);
This query would mix customer detail table and order table and return all values that matches the where clause on the left table

Related

How to create a function that totals an order with several items?

I need to create a function which will return the total of an order. I've been given three tables with the following variables
Table 1 - Order
Order_ID
Date_Placed
Date_Fulfilled
Table 2 - Order Product
Order_ID
Product_ID
Product_Quantity
Table 3 - Product
Product_ID
Price
I'm struggling to put together a coherent function. Any help would be greatly appreciated.
I've already attempted to set up the function with joins between both tables, but am unable to figure out where I should be putting my equation.
BEGIN
SELECT order.order_id, SUM(product.price * order_item.quantity)
FROM `order`
JOIN `order_item` ON order.order_id = order_product.order_id
JOIN `product` ON order_product.product_id = product.product_id;
END $$
You might be surprised, but the orders table is not needed for this query. You can just aggregate off the other two tables:
SELECT oi.order_id, SUM(p.price * oi.quantity)
FROM order_item oi JOIN
product p
ON po.product_id = p.product_id
GROUP BY oi.order_id;
You'll need to take your select statement, and group it by your order.order_id. That way you'll have one row per order, with the sum total of that order.
SELECT order.order_id, SUM(product.price * order_item.quantity) as total_price
FROM `order`
JOIN `order_item` ON order.order_id = order_product.order_id
JOIN `product` ON order_product.product_id = product.product_id
GROUP BY order.order_id
this will work:
SELECT order.order_id, SUM(product.price * order_item.quantity)
FROM order o,
JOIN order_item oi,
JOIN product p where
o.order_id = oi.order_id and
oi.product_id = p.product_id
group by order_product.product_id = product.product_id;

SQL sum from single table with join

I have two table orders and orderitems.
order table has id,order_total,recieved_amount
orderitems table has id,order_id,name,total_item
I want the sum of recieved_amount, order_total from the order table and sum of total_item from orderitems. so I used
SELECT SUM(`received_amount`) as totalRecieved,
SUM(`order_total`) as orderTotal
FROM `orders` AS `Order`
LEFT JOIN `order_items` AS `OrderItems`
ON (`OrderItems`.`order_id`=`Order`.`id`)
and
SELECT SUM(`received_amount`) as totalRecieved,
SUM(`order_total`) as orderTotal
FROM `orders` AS `Order`
LEFT JOIN `order_items` AS `OrderItems`
ON (`OrderItems`.`order_id`=`Order`.`id`)
group by order.id
but none of them is giving me the correct result.
You are aggregating at two levels of your data hierarchy. This causes a problem with Cartesian products, for each order.
The solution is to aggregate along order_items before doing the join:
SELECT SUM(received_amount) as totalRecieved,
SUM(order_total) as orderTotal
FROM orders o LEFT JOIN
(SELECT oi.order_id, SUM(total_items) as total_items
FROM order_items oi
GROUP BY oi.order_id
) oi
ON oi.order_id = o.id;
As an alternative, you can benefit from cte structure or a temp table like below:
;with cte (order_id, SumTotalItems) as (
SELECT oi.order_id, SUM(total_items) as SumTotalItems
FROM order_items oi
GROUP BY oi.order_id
)
select sum(o.receivedamount) as SumReceivedAmount
, sum(o.order_total) as SumOrderTotal
, cte.SumTotalItems
from orders o
left outer join cte on o.id = cte.order_id

Sql Query for finding Orders having same order lines

How I can write a query that can find me orders having same order lines (details)?
Sample Data
Table: Order
ORDER_ID
--------
A
B
C
D
Table: OrderDetails
OrderID ProductID
------------------
A ProductX
A ProductY
A ProductZ
B ProductX
B ProductY
C ProductZ
D ProductX
D ProductY
D ProductZ
Now I want to pass ProductX,ProductY,ProductZ and get back A and D.
Can this be done in one query?
Maybe something like this is what you want?
SELECT DISTINCT Orders.OrderID
FROM Orders
INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID
WHERE OrderDetails.ProductID IN ('ProductX', 'ProductY', 'ProductZ')
GROUP BY Orders.OrderID
HAVING COUNT(*) = 3
Also note that Order is a reserved keyword and should not be used as a table name.
SELECT OrderId FROM
(SELECT DISTINCT o.OrderId, p.Product
FROM Orders o
INNER JOIN OrderDetails p
ON o.OrderId = p .OrderId
WHERE p.Product IN ('ProductX', 'ProductY', 'ProductZ') ) tab
GROUP BY OrderId
HAVING COUNT(*) = 3
I have done the required thing without using the Order table..
SELECT id from ProductT
group by id
having count(*)=3;
SQL Fiddle
Try this
SELECT P.OrderID
FROM Order1 P JOIN OrderDetails D ON
P.OrderID = D.OrderID
WHERE P.OrderID IN (SELECT OrderID FROM OrderDetails WHERE ProductID IN ('ProductX', 'ProductY', 'ProductZ'))
Having Count(P.OrderID)=3
GROUP BY P.OrderID
FIDDLE DEMO

SQL Server: fill Null Fields from Not Null Column for multiple rows having same id

I built following Select query to get below results
SELECT Orders.OrderID, OrderDetails.ProductCode, OrderDetails.Coupon
From Orders, OrderDetails
WHERE Orders.OrderID=OrderDetails.OrderID
Results
Order ID Product Code Coupon
22 A
22 B XYZ
22 C
23 D 123
24 E
I want it to display like this:
Order ID Product Code Coupon
22 A XYZ
22 B XYZ
22 C XYZ
23 D 123
24 E
so that it fills empty coupons from not empty coupon field where order id matches.
Your help will be greatly appreciated. Thanks.
SELECT
t1.OrderID,
t1.ProductCode,
MAX(ISNULL(t2.Coupon,'')) as CouponCode,
t1.CustomerName
--Here you have select list by using alias 't'
--don't forget it to add in group by clause
FROM
(
select O.OrderID,OD.ProductCode,OD.CouponCode as Coupon,C.CustomerName
--Here add the list of columns
from Orders O
inner join OrderDetails OD on O.OrderID=OD.OrderID
Inner join customers C on O.CustomerID=C.CustomerID
)t1
INNER JOIN (
select O.OrderID
from Orders O
inner join OrderDetails OD on O.OrderID=OD.OrderID
Inner join customers C on O.CustomerID=C.CustomerID
)t2 ON
CAST(t1.OrderID AS VARCHAR)=
CAST(t2.OrderID AS VARCHAR)
GROUP BY t1.OrderID,
t1.ProductCode,
t1.CustomerName
--Add the extra fields.
order by t1.OrderID
SQL Fiddle with Your Data
Assuming Coupon is unique for each OrderID.
SELECT o1.OrderID, o2.Coupon
FROM OrderDetails o1 LEFT JOIN
(SELECT DISTINCT OrderID, Coupon FROM OrderDetails WHERE NOT Coupon IS NULL) AS o2 ON o1.OrderID = o2.OrderID
This is kind of ugly but does the job:
SELECT o.OrderID, od1.ProductCode, COALESCE(od1.Coupon,od2.Coupon)
From
Orders o
inner join
OrderDetails od1
on
o.OrderID=od1.OrderID
left join
(select OrderID,MAX(Coupon) as Coupon from OrderDetails
where Coupon is not null group by OrderID) od2
on
o.OrderID=od2.OrderID
It's using GROUP BY and MAX to ensure that there's only one row in od2 for each OrderID value, even if multiple rows in OrderDetails already have Coupon set.

Joining on a group by

Lets say that I have three tables, customers, orders and orderDetails.
I'm doing this:
SELECT orders.ordersId, sum(orderDetails.total)
FROM orders
LEFT OUTER JOIN orderDetails ON orders.ordersId = orderDetails.ordersId
GROUP BY orders.ordersId
But lets say the orders table contains customersId. How do I join on the customers table so that I can also add the customer's name to the fields selected?
Thanks,
Barry
SELECT orders.ordersId, sum(orderDetails.total), customer.name
FROM orders
LEFT OUTER JOIN orderDetails ON orders.ordersId = orderDetails.ordersId
LEFT OUTER JOIN customer on customer.customerid = orders.customerid
GROUP BY orders.ordersId , customer.name
Try that out or something similar.
you can do it this way, which will let you get more than customer name if needed:
SELECT o.ordersId, o.orderTotal, c.customername, c.(other customer data)
FROM
(
SELECT orders.ordersId
, sum(orderDetails.total) as orderTotal
, orders.customersid
FROM orders
LEFT OUTER JOIN orderDetails
ON orders.ordersId = orderDetails.ordersId
GROUP BY orders.ordersId, orders.customersid
) o
LEFT JOIN customers c
ON o.customersid = c.customersid