What expression is missing in this sql command? - sql

I put in this SQL command and it tells me I am missing an expression. What is it?
SELECT Warehouse_Number, DISTINCT COUNT(DISTINCT Order_Number) AS NumberOfOrders
FROM Part, Order_Line
WHERE Part.Part_Number=Order_Line.Part_Number
GROUP BY Warehouse_Number;

Consider:
select p.warehouse_number, count(distinct ol.order_number) as numberoforders
from part p
inner join order_line ol on ol.part_number = p.part_number
group by p.warehouse_number;
That is:
use distinct only once, within aggregate function count(); the other way to use that keyword is to put it directly after select (as in select distinct ...), but this does not make sense for an aggregation query to start with
use standard joins! Implicit joins (with commas in the from clause and join conditions in the where clause) are archaic syntax, that should not be used in new code
table aliases make the query easier to write and read
in a multi-table query, all columns should be qualified with the (alias of the) table they belong to - I assumed that warehouse_number comes from part

The distinct modifier can only appear at the beginning of the select list or inside an aggregate function, not before a non-first select element.
Since you're using a group by clause you don't need it anyway - just drop it, and you should be OK:
SELECT Warehouse_Number, COUNT(DISTINCT Order_Number) AS NumberOfOrders
FROM Part, Order_Line
WHERE Part.Part_Number=Order_Line.Part_Number
GROUP BY Warehouse_Number;

I think you meant
SELECT Warehouse_Number,
COUNT(DISTINCT Order_Number) AS NumberOfOrders
FROM Part as P
join Order_Line as OL --Possible inner join
on P.<some variable> = OL.<some variable> --Hopefully a key between variables
WHERE Part.Part_Number=Order_Line.Part_Number
GROUP BY Warehouse_Number;

Related

How can I write this correlated subquery by using with clause?

As you can see OrderDate is fetching details from ORDERS but ORDERS has reference in outer query, if I bring inner subquery and store in an object for using with clause that gives me an error. for reference of table I am putting link of tables to follow :
{tables links: source(w3school.com/sql)
orders- https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
products- https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all }
Please suggest method to rewrite this subquery by using with clause.
SELECT
OBJECT
FROM
( SELECT DISTINCT
( select distinct ORDERS.OrderDate
from
PRODUCTS
where
PRODUCTS.CategoryID = ORDERS.EmployeeID) AS OBJECT
FROM
ORDERS)
The code does run on w3schools.com, but that does not make it correct SQL.
See DBFIDDLE which has the first records of the products table, and some records from the ORDERS table, which shows an error ("Every derived table must have its own alias")
When correcting the query to:
SELECT
xyz.*
FROM
( SELECT DISTINCT
( select distinct ORDERS.OrderDate
from
PRODUCTS
where
PRODUCTS.CategoryID = ORDERS.EmployeeID) AS OBJECT
FROM
ORDERS) xyz
You will get an answer in MySQL, see: DBFIDDLE

GROUP BY not working in left join query

I m trying to use group by clause in left join sql query and it is not working.
Please help me out, thanks in advance.
SELECT Cust_Mst_Det.Cust_Hd_Code,
Cust_Mst_Det.First_Name,
SL_HEAD20152016.vouch_date AS invoice_2,
SL_HEAD20142015.vouch_date AS invoice_1,
Cust_Mst_Hd.EMail
FROM Cust_Mst_Det
LEFT JOIN SL_HEAD20142015 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20142015.Member_Code
LEFT JOIN SL_HEAD20152016 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20152016.Member_Code
LEFT JOIN Cust_Mst_Hd ON Cust_Mst_Det.Cust_Hd_Code=Cust_Mst_Hd.Cust_Hd_Code
WHERE cust_mst_det.first_name!='NIL'
GROUP BY Cust_Mst_Det.Cust_Hd_Code
ORDER BY SL_HEAD20152016.vouch_date DESC,
SL_HEAD20142015.vouch_date
I'm not sure which DBMS you are using, but on an Oracle your query will not work at all.
First issue: The GROUP BY statement is used in conjunction with the aggregate functions to group the result-set by one or more columns. You do not have any aggregating function in your SELECT statement (count, max, etc.)
Second issue: you must specify all columns from SELECT statement in your GROUP BY statement (excluding columns that represents results of aggregation).
As I said I don't know which DB is used by you, but those two points should be applicable for the most of SQL standards.
It appears that it is impossible to use an ORDER BY on a GROUP BY summarisation. My fundamental logic is flawed. I will need to run the following subquery.
ex :
SELECT p.*, pp.price
FROM products p
LEFT JOIN ( SELECT price FROM product_price ORDER BY date_updated DESC ) pp
ON p.product_id = pp.product_id GROUP BY p.product_id;
This will take a performance hit but as it is the same subquery for each row it shouldn't be too bad.

Column 'ITEMS_MASTER.QUANTITY' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

Select
ID.ITEM_MODEL,
SUM(ID.AMOUNT) as Total_Amount,
AVG(ID.RATE) as Avg_Rate,
IM.QUANTITY
From
ITEM_DETAILS ID
inner join
ITEMS_MASTER IM on ID.ITEM_MODEL = IM.ITEM_MODEL
where IM.ITEM_MODEL='keyboard'
Group by
ID.ITEM_MODEL
I wrote above query, I want to extract data from two tables ITEM_DETAILS and ITEMS_MASTERS but when I run this it is showing me this error:
Column 'ITEMS_MASTER.QUANTITY' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can anyone suggest me the correct way of doing this.
Try this:
SELECT IM.ITEM_MODEL, IM.QUANTITY,
SUM(ID.AMOUNT) as Total_Amount,
AVG(ID.RATE) as Avg_Rate
FROM ITEMS_MASTER IM
INNER JOIN ITEM_DETAILS ID ON ID.ITEM_MODEL = IM.ITEM_MODEL
WHERE IM.ITEM_MODEL = 'keyboard'
GROUP BY IM.ITEM_MODEL, IM.QUANTITY
Generally speaking, when you have a parent table (ITEMS_MASTER) that has multiple rows from a child table (ITEM_DETAILS), you want to GROUP BY the columns in your parent table. This is slightly more logical and on some databases this performs better.
You could try adding IM.QUANTITY to the group by clause,
Group by
ID.ITEM_MODEL,
IM.QUANTITY

AS being ignored in a subquery

Still learning SQL here... I have part of a subquery:
(Select MAX(cost) AS Cost_of_Car FROM Car_Purchase)
But it does not take my label just uses the one from the table, in this case "cost"
Any ideas?
EDIT: Just realized I could in my SELECT statement call out AS "NAME OF COLUMN", but why does it not accept AS in the subquery?
POSTING FULL QUERY
SELECT CAR.name, Car_Purchase.cost_per_night, Car_Purchase.description
FROM Car_Purchase
JOIN CAR ON Car_Purchase.purchase_id = CAR.purchase_id
GROUP BY CAR.name, Car_Purchase.cost_per_night, Car_Purchase.description
HAVING Car_Purchase.cost = (SELECT MAX(cost) AS Cost_of_Car FROM Car_Purchase)
The AS keyword is not being ignored.
You're using subquery in where clause. Remember, where clause is used for filtering the query result, not for displaying the data.
If you want to see how AS work in subquery, try this:
SELECT CAR.name, Car_Purchase.cost_per_night, Car_Purchase.description, Cost_of_Car
FROM Car_Purchase
JOIN CAR ON Car_Purchase.purchase_id = CAR.purchase_id
join (SELECT MAX(cost) AS Cost_of_Car FROM Car_Purchase) subquery
ON Car_Purchase.cost = subquery.Cost_of_Car
GROUP BY CAR.name, Car_Purchase.cost_per_night, Car_Purchase.description
In this query, I put the subquery in from clause. So your query result now have Cost_of_Car column and you can display it in select clause.
In fact, since, as noted by others the Max(Cost) is not being used elsewhere in the query, you don't need to alias it at all. And since you don't have a aggregate function anywhere in the sql it does not need to be a group By query
Select cp.name, cp.Cost CostOfCar,
cp.cost_per_night, cp.description
From Car_Purchase cp Join Car c
On c.purchase_id = cp.purchase_id
Where cp.cost = (SELECT MAX(cost) FROM Car_Purchase)
Is sufficient and should work

Passing Data Through A Three Tiered Scalar Subquery

I have a query, that has three tiers. That is to say, I have a main query, which has a scalar subquery, which also contains a scalar subquery.
The bottom level scalar query is returning two different values two which the mid-level subquery is returning an average of. However, instead of the bottom level query receiving the current value, it is averaging ALL of the values in the table.
Does anyone know how to properly pass the value of the current top level query result to the bottom subquery?
Code Example:
Select Product,
Description,
(Select Avg(Mfg_Cost, Purchasing_Cost)
FROM (Select Mfg_Cost,
Purchasing Cost
From Cost
Where Cost.Product = Products.Product))
From Products;
Can't you just use a JOIN and GROUP BY, like so:
Select p.Product,
p.Description,
Avg(c.Mfg_Cost),
Avg(c.Purchasing_Cost)
From Products p
INNER JOIN
Cost c
ON c.Product = p.Product
GROUP BY p.Product, p.Description;
In general, if you need to return more than one value from a subquery:
Select p.Product,
p.Description,
q2.AvgMfg_Cost,
q2.AvgPurchasing_Cost
From Products p INNER JOIN
(
Select c.Product,
Avg(c.Mfg_Cost) AS AvgMfg_Cost,
Avg(c.Purchasing_Cost) AS AvgPurchasing_Cost
From Cost c
Group by c.Product
) AS q2
on q2.Product = p.Product;
In Microsoft SQL Server, you can also use a Common Table Expression (CTE)