SQL column name is keyword "category" - sql

This query works:
SELECT product_name, unit_price, order_due_date
FROM orders
FULL OUTER JOIN products ON orders.product_id = products.product_id
WHERE product_name = 'bun';
whereas this one throws an error:
ORA-00936: "missing expression"
SELECT product_name, unit_price, order_due_date
FROM orders
FULL OUTER JOIN products ON orders.product_id = products.product_id
WHERE [category] = 'soft drink';
I can't figure what's wrong with the second

When you have multiple tables in a query, you should always qualify column names. In your first query, the WHERE clause is undoing the FULL JOIN. In fact, I am guessing that an INNER JOIN is most appropriate. How would an order have a product not in the products table?
SELECT p.product_name, ?.unit_price, o.order_due_date
FROM orders o INNER JOIN
products p
ON o.product_id = p.product_id
WHERE p.product_name = 'bun';
As for your second query, [ and ] are not delimiters in Oracle. Either leave them out:
WHERE category = 'soft drink'
Or, if for some obscure reason the column name actually has those characters, then use double quotes:
WHERE "[category]" = 'soft drink';

Related

How to pick first or random row from multiple rows returned in SQL?

Code:
select product.code, product.description, salesorder.number, customer.name, 'Quantity' as Quantity, barcode.barcode
from salesorderline
join salesorder on salesorderline.salesorderid = salesorder.id
join product on salesorderline.productid = product.id
join barcode on product.id = barcode.productid
join customer on salesorder.customerid = customer.id
Output:
Image
Problem:
More than one codes are returned, because there is multiple barcodes attached to it.
Within the database, more than 1 barcode is attached to the codes.
How can I return just 1 random value of barcode instead of all? that are attached to the code.
SQL DATABASE:
Database Is stored in Microsoft SQL
What I have tried:
select product.code, product.description, salesorder.number, customer.name, 'Quantity' as Quantity, barcode.barcode
from salesorderline
join salesorder on salesorderline.salesorderid = salesorder.id
join product on salesorderline.productid = product.id
join barcode on product.id = barcode.productid
join customer on salesorder.customerid = customer.id
group by barcode.barcode
but the error is:
Error: Column 'product.code' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
In SQL Server
SELECT TOP 1 MyColumn FROM MyTable
ORDER BY NEWID()
There's no RAND in SQL server as far as i know
but you can use NEWID() which create a unique value which is basiclly the same as RAND()
More Info about NEWID() can be foudn at MSDN
I would recommend cross apply:
select p.code, p.description, so.number, c.name,
'Quantity' as Quantity, bc.barcode
from salesorderline sol join
salesorder so
on sol.salesorderid = so.id join
product p
on sol.productid = p.id join
customer c
on so.customerid = c.id cross apply
(select top (1) bc.*
from barcode bc
where p.id = bc.productid
order by newid()
) bc;
Technically, apply implements lateral joins. These are a very powerful type of join. In this case, the join is equivalent to a correlated subquery, but a correlated subquery that returns multiple columns.

using subquery in order to join columns from two tables

i started learning SQL and there is something i dont understand
i want to take the columns product_id and product_name from Production.products
and join it with the quantity column from the Production.stocks table
but instead of using join i want to use a subquery.
this is the code i wrote so far:
and i don't understand why it isn't working :(
SELECT P.product_id, P.product_name,(
SELECT S.quantity
FROM Production.stocks AS S
WHERE S.product_id = P.product_id)
FROM Production.products as P;
First, let's clear up the fact that it is not recommended to use a subquery at all. Do it only for your own research reasons; if you have performance or code clarity in mind, go with the simple join.
When you make a subquery on the SELECT clause by enclosing it in parenthesis, you are forcing the result to be one single value. If not, you get the error you receive.
Usually, subqueries are used in the FROM clause, where they should be given a name and then represent a table. Like this:
SELECT P.product_id, P.product_name,S.quantity
FROM Production.products as P
inner join
(
SELECT quantity
FROM Production.stocks
) as S on S.product_id = P.product_id
You can see from the simplicity of the subquery of how little use it is.
You can use SUM keyword for prevent error and give you total quatity.
SELECT P.product_id, P.product_name,(
SELECT SUM(S.quantity)
FROM Production.stocks AS S
WHERE S.product_id = P.product_id)
FROM Production.products as P;
I don't see a need at all for a subquery.
If the products are unique entities then surely a join onto the stocks table and doing a sum on the quantity would be more beneficial in terms of query performance
SELECT
Production.Products.Product_id,
Production.Products.product_name,
SUM(Production.Stocks.quantity) AS Quantity
FROM
Production.Products
LEFT JOIN
Production.Stocks
ON
Production.Stocks.product_id = Production.Products.product_id
GROUP BY
Production.Products.product_id,
Production.Products.product_name
If you need it to quote stock quantities by store then you need to add an addition join onto stores and add the store to the select and group by clause like so
SELECT
Production.Products.Product_id,
Production.Products.product_name,
Sales.Stores.store_name,
SUM(Production.Stocks.quantity) AS Quantity
FROM
Production.Products
LEFT JOIN
Production.Stocks
ON
Production.Stocks.product_id = Production.Products.product_id
LEFT JOIN
Sales.Stores
ON
Production.Stocks.store_id = Sales.Stores.store_id
GROUP BY
Production.Products.product_id,
Production.Products.product_name,
Sales.Stores.store_name
Hope that helps
did you mean select all data from products table and show quantity column for each product?
SELECT P.product_id, P.product_name, isnull(s.quantity, 0) as Quantity
FROM Production.products as P
left join Production.stocks AS S
on p.product_id = S.product_id
if you have one to many relation with Products and Stocks you should use subquery like this
SELECT P.product_id, P.product_name, isnull(s.quantity, 0) as Quantity
FROM Production.products as P
left join (
select product_id, sum(quantity) as Quantity
from Production.stocks
group by product_id)
as S on p.product_id = S.product_id
it will be produced aggregated sum value for quantity field

ORA-00933: SQL command not properly ende

SELECT S.SUPPLIER_NAME,P.PRODUCT_NAME,O.ORDER_ID,O.QUANTITY
FROM SUPPLIERS AS S
INNER JOIN PRODUCT AS P
ON S.PRODUCT_ID = P.PRODUCT_ID
INNER JOIN ORDERS AS O
ON P.PRODUCT_ID = O.ORDER_ID;
WHEN i am joining three table
ORA-00933: SQL command not properly ended.
Oracle does not use as for table aliases. Try this version:
SELECT S.SUPPLIER_NAME, P.PRODUCT_NAME, O.ORDER_ID, O.QUANTITY
FROM SUPPLIERS S JOIN
PRODUCT P
ON S.PRODUCT_ID = P.PRODUCT_ID JOIN
ORDERS O
ON P.PRODUCT_ID = O.ORDER_ID;
The syntax error comes from the S after the AS. The AS is considered the table alias, and a join condition or SQL clause (or horrors a comma) is expected next.
Oracle ALIASES can be used to create a temporary name for columns or tables.To make the heading of the output more meaningful and to improve readability of a query. Refer link
For example if you want to change the column 'SUPPLIER_NAME' As SUPPLIERNAME. This query will return the ResultSet column as 'SUPPLIERNAME'.
SUPPLIERS S --> S is temporary name for the table 'SUPPLIERS'. Refer below modification.
SELECT S.SUPPLIER_NAME,P.PRODUCT_NAME,O.ORDER_ID,O.QUANTITY
FROM SUPPLIERS S
INNER JOIN PRODUCT P
ON S.PRODUCT_ID = P.PRODUCT_ID
INNER JOIN ORDERS O
ON P.PRODUCT_ID = O.ORDER_ID;

Cartesian products and selects in the from clause

I need to use a select in the from clause but I keep getting an Cartesian product.
select
customer.customer_name
,orders.order_date
,order_line.num_ordered
,order_line.quoted_price
,part.descript
,amt_billed
from (select order_line.num_ordered*part.price as amt_billed
from order_line
join part
on order_line.part_num = part.part_num
) billed
,customer
join orders
on customer.customer_num = orders.customer_num
join order_line
on orders.order_num = order_line.order_num
join part
on order_line.part_num = part.part_num;
Don't bother looking at the rest too hard. I already know that if I remove both the subselect in the from clause and amt_billed in the select clause I don't get the Cartesian product. What am I doing wrong that's causing the Cartesian product?
The reason for Cartesian product is, you didn't join the sub-select with orders or Part table.
First of all you don't need that sub-select
SELECT customer.customer_name,
orders.order_date,
order_line.num_ordered,
order_line.quoted_price,
part.descript,
order_line.num_ordered * part.price AS amt_billed
FROM customer
JOIN orders
ON customer.customer_num = orders.customer_num
JOIN order_line
ON orders.order_num = order_line.order_num
JOIN part
ON order_line.part_num = part.part_num;

SQL not a GROUP BY expression with OracleSQL and InnerQuery Error

I have little problem with my SQL query.
I want to get my CUSTOMERS table id, name, surname, and all money they spent on my shop i've created.
SELECT o.CUSTOMER_ID AS "ID", c.name AS "Name", c.SURNAME AS "Surname",
(SELECT op.AMOUNT * p.PRICE
FROM PRODUCTS p
WHERE p.id = op.PRODUCT_ID) AS "Money spent"
FROM ORDERS o
LEFT JOIN CUSTOMERS c ON c.ID = o.CUSTOMER_ID
LEFT JOIN ORDERS_PRODUCTS op ON op.ORDER_ID = o.id
GROUP BY o.CUSTOMER_ID;
And i have error message like this:
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:
Error at Line: 1 Column: 31
I have to say, that i have to use GroupBy clause, because i have this in my school project requirements.
And this is my base diagram, if it could help you.
http://i61.tinypic.com/2d1okut.jpg
As you can see in the ORACLE docs
SelectItems in the SelectExpression with a GROUP BY clause must contain only aggregates or grouping columns.
This means that if you only group by o.CUSTOMER_ID, all the other fields in the select list must be aggregate functions (like COUNT, MAX, etc.).
In the case of fields that repeat values in each group (as name and surname) you should include them in the GORUP BY clause.
To include the sum of money spent, you could add another LEFT JOIN with PRODUCTS and select SUM(op.amount*p.price) without a subquery.
That would be
SELECT o.CUSTOMER_ID AS "ID", c.name AS "Name", c.SURNAME AS "Surname",
SUM(op.AMOUNT*p.PRICE) AS "Money spent"
FROM ORDERS o
LEFT JOIN CUSTOMERS c ON c.ID = o.CUSTOMER_ID
LEFT JOIN ORDERS_PRODUCTS op ON op.ORDER_ID = o.id
LEFT JOIN PRODUCTS p ON p.id = op.PRODUCT_ID
GROUP BY o.CUSTOMER_ID, c.name AS "Name", c.SURNAME
ORDER BY o.CUSTOMER_ID, c.name AS "Name", c.SURNAME;
Remember always to define the sort order of your queries, otherwise it will be undefined.