Select multiple selected values from a column from each row - sql

I am new to SQL so please bear with me. I am trying to select rows only with specific product codes. When I run it for one selection without OR statement in the below query results are fine but as soon I add another choice with OR statement the results are not accurate. It looks like it keeps putting ProductCode MW-BShorts-0009 against each OrderID.
SELECT
Orders.OrderID, OrderDetails.ProductCode
FROM
Orders, OrderDetails
WHERE
Orders.OrderID = OrderDetails.OrderID
AND OrderDetails.ProductCode = 'MacFRC'
OR OrderDetails.ProductCode = 'MW-BShorts-0009'

Use IN clause and its better to use Join instead of Cartesian product
SELECT Orders.OrderID, OrderDetails.ProductCode
FROM Orders
JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
AND OrderDetails.ProductCode IN ('MacFRC','MW-BShorts-0009')

From your above query it looks like you dont even need a join or select from the Orders table
select OrderID, ProductCode
from OrderDetails
where ProductCode IN ('MacFRC','MW-BShorts-0009')

AND has precedence over OR so you'd need to enclose the OR clause in parentheses:
SELECT Orders.OrderID, OrderDetails.ProductCode
FROM Orders, OrderDetails
WHERE Orders.OrderID = OrderDetails.OrderID
AND
(OrderDetails.ProductCode = 'MacFRC'
OR OrderDetails.ProductCode = 'MW-BShorts-0009')
However you should use a JOIN clause instead of adding a WHERE condition to match the tables , and can use IN instead of ORing two conditions:
SELECT Orders.OrderID, OrderDetails.ProductCode
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
WHERE OrderDetails.ProductCode IN ('MacFRC', 'MW-BShorts-0009')

You can use IN as Srikanth has mentioned. But you need to understand the concept of operator precedence as well. In your case, you are saying "Either Orders.OrderID must equal OrderDetails.OrderID and OrderDetails.ProductCode must equal 'MacFRC', or OrderDetails.ProductCode must equal 'MW-BShorts-0009'." What you want is for the OrderID = ProductCode criterion to apply to either ProductCode.
All you need to do is override the default precedence with parentheses, same as you would if you want to do an addition before a multiplication. Like this:
SELECT Orders.OrderID, OrderDetails.ProductCode
FROM Orders, OrderDetails
WHERE Orders.OrderID = OrderDetails.OrderID
AND (OrderDetails.ProductCode = 'MacFRC'
OR OrderDetails.ProductCode = 'MW-BShorts-0009')

Related

Simple SQL Script in W3Schools not working

I am currently learning SQL and using the W3Schools Tryit Editor to play around. I am trying to update a table using a lookup from another table. I looked online and figured out the following code to run:
UPDATE OrderDetails
SET OrderDetails.ProductID = Orders.CustomerID
FROM Orders
INNER JOIN OrderDetails
ON OrderDetails.OrderID = Orders.OrderID
But it is coming up with the following error: "Error 1: could not prepare statement (1 near ".": syntax error)"
Is there a problem with my code or are there things that W3Schools doesn't want to run?
The update with join syntax is specific for each db
The query you are using is valid for SQLSERVER
UPDATE OrderDetails
SET OrderDetails.ProductID = Orders.CustomerID
FROM Orders
INNER JOIN OrderDetails
ON OrderDetails.OrderID = Orders.OrderID
but not for my MySQL
UPDATE OrderDetails
INNER JOIN OrderDetails
ON OrderDetails.OrderID = Orders.OrderID
SET OrderDetails.ProductID = Orders.CustomerID
This works:
UPDATE OrderDetails
SET ProductID = (SELECT CustomerID FROM Orders WHERE OrderDetails.OrderID = Orders.OrderID)
WHERE OrderID IN (SELECT OrderID FROM Orders);
Is this what you want?

Left Join and Sum Each Individual Row

I have a table named orders (orderID, customerID, purchaseDate, and paymentType) and orderLine (orderID, upc, productName, quantity, price). I'm trying to join these two tables so that it primarily shows the orders table but then has a total price column for each order on the far right. This is what I have so far but it's adding the total for every single row into one. I want each individual row to have their own sum by multiplying quantity*price based on the orderID.
SELECT orders.orderID, SUM(orderLine.price * orderLine.quantity)
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
You need to add group by clause
SELECT orders.orderID, SUM(orderLine.price * orderLine.quantity)
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
grou by orders.orderID
SELECT orders.orderID, (SUM(orderLine.price * orderLine.quantity) Over (Order
By orders.orderID))
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
Group By orders.orderID
You want all orders, so start with orders. Table aliases also make the query easier to write and to read:
SELECT o.orderID, SUM(ol.price * ol.quantity)
FROM orders o LEFT JOIN
orderLine ol
ON o.orderID = ol.orderID
GROUP BY o.orderID;
Then the answer to your question is GROUP BY.
You would have a very poor data model if you have orderlines that don't have a corresponding order, which is what your version of the query suggests.

Sql Aggregate function with join

SELECT ORDERS.ORDERID,
ORDERS.CUSTOMERID,
ORDERS.EMPLOYEEID,
ORDERDETAILS.PRODUCTID,
ORDERDETAILS.UNITPRICE,
ORDERDETAILS.QUANTITY,
COUNT(ORDERS.ORDERID)
FROM ORDERS
LEFT JOIN ORDERDETAILS ON ORDERS.ORDERID=ORDERDETAILS.ORDERID
GROUP BY ORDERDETAILS.ORDERID
ERROR:Column 'ORDERS.OrderID' is invalid in the select list because it
is not contained in either an aggregate function or the GROUP BY
clause.
For using aggregate function selected column will also need to include in group by clause
SELECT
ORDERS.ORDERID,ORDERS.CUSTOMERID,ORDERS.EMPLOYEEID,ORDERDETAILS.PRODUCTID,ORD ERDETAILS.UNITPRICE,ORDERDETAILS.QUANTITY,
COUNT(ORDERS.ORDERID)
FROM ORDERS LEFT JOIN ORDERDETAILS ON
ORDERS.ORDERID=ORDERDETAILS.ORDERID
GROUP BY ORDERDETAILS.ORDERID,ORDERS.CUSTOMERID,ORDERS.EMPLOYEEID,ORDERDETAILS.PRODUCTID,ORD ERDETAILS.UNITPRICE,ORDERDETAILS.QUANTITY
Presumably, you intend this:
SELECT o.ORDERID, o.CUSTOMERID, o.EMPLOYEEID,
COUNT(od.ORDERID) as NUM_PRODUCTS
FROM ORDERS o LEFT JOIN
ORDERDETAILS od
ON o.ORDERID = od.ORDERID
GROUP BY o.ORDERID;
This produces one row per ORDERID with a count of the number of products (or more specifically orderdetails rows) in each order.
Notes:
All unaggregated columns in the SELECT should be GROUP BY keys.
You don't want to include unaggregated columns from ORDERDETAILS in the SELECT, because then an ORDER might have multiple rows in the result set.
You do want to use table aliases, so the query is easier to write and to read.

SQL: List the products ordered on a Monday

I am trying to query products that were ordered on a Monday and I am confused on how to format or extract the specific day-of-week to the orderDate Value...
Here's what I have.. (I am fairly new to SQL, so I am probably way off.. )
SELECT Products.productName, OrderDetails.orderNumber, Orders.orderDate
FROM Orders, OrderDetails, Products
WHERE Orders.orderDate LIKE '%Monday%;
Thanks in advance!
SELECT Products.productName ,
OrderDetails.orderNumber ,
DATENAME(dw,Orders.orderDate),
Orders.orderDate
FROM Orders
inner join OrderDetails
on OrderDetails.OrderID = Orders.ID
inner join Products
on Products.ID = Orders.ProductID
WHERE DATENAME(dw,Orders.orderDate) = 'Monday'
SELECT
Products.
productName,
OrderDetails.orderNumber,
Orders.orderDate
FROM
Orders
JOIN OrderDetails ON Orders.OrdersID = OrderDetails.OrderID
JOIN Products ON OrderDetail.ProductID = Products.ProductID
WHERE
DATENAME(DW,Orders.orderDate) = 'Monday'
Use Datepart function, DATEPART(W,[DATE]) will return week day. (1 as monday)
SELECT Products.productName, OrderDetails.orderNumber, Orders.orderDate
FROM Orders, OrderDetails, Products
WHERE DATEPART(w,Convert(Date,Orders.orderDate))=1
NOTE : This will give result in Cartesian product. please do join these tables properly
You can use the sql date function:
Oracle: to_char(Orders.orderDate,'D')
MySql: DAYOFWEEK(Orders.orderDate)

SQL: How to select two input parameters from three tables?

Okay, this is related to database given on http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
I need to find list of Customers,OrderID, ProductID for orders from Spain.
The table 'Orders' has OrderID and table 'Products' consists of ProductID whereas the table 'OrderDetails' consists of OrderID and ProductID. I use the following code but I get an error message 'Error: 1 ambiguous column: OrderID'
Here is my code
SELECT CustomerName, Country, OrderID, ProductID
FROM Customers, Orders, Products, OrderDetails
WHERE Customers.CustomerID = Orders.CustomerID
AND Orders.OrderID = OrderDetails.OrderID
AND Products.ProductID = OrderDetails.ProductID AND Country = 'Spain'
Can someone correct any mistake?
You need to use the alias names like this:
SELECT Customers.CustomerName,
Customers.Country, --Specify the correct table in which you have Country column
Orders.OrderID,
Products.ProductID
FROM Customers
inner join Orders ON Customers.CustomerID = Orders.CustomerID
inner join OrderDetails on Orders.OrderID = OrderDetails.OrderID
inner join Products on Products.ProductID = OrderDetails.ProductID
where Customers.Country = 'Spain'
Also try to avoid comma seperated JOINS. A good read: Bad habits to kick : using old-style JOINs