AS being ignored in a subquery - sql

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

Related

What expression is missing in this sql command?

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;

Sql - "missing right parenthesis" error explanation

My code is syntactically correct and I don't think that I need any parenthesis,
however it keeps coming up with an error "00907. 00000 - "missing right parenthesis"" without any explanation of the cause
SELECT DISTINCT BG.name
FROM Brand_Group BG
WHERE BG.pid=(SELECT P.pid
FROM Indicia_Publisher IP
LEFT JOIN Publisher P ON IP.pid=P.pid
WHERE (IP.cid=(SELECT Country.cid
FROM Country
WHERE Country.name='Belgium') AND ROWNUM<=1)
GROUP BY P.pid
ORDER BY COUNT(P.pid));
The issue is to do with the ORDER BY in the comparison subquery - it's not valid syntax, which you can see by running the following query:
SELECT * FROM dual WHERE dummy IN (SELECT dummy FROM dual ORDER BY dummy);
Remove the ORDER BY clause and your query should run without issue.
Also, if you're wanting to get distinct rows returned and you're not using an aggregate function (e.g. MAX, SUM, etc), then you should use DISTINCT, not GROUP BY - it makes your intention much clearer. However, since you've restricted the results to a single row with and rownum = 1, there's not much point in using either!
Your query should probably be something along the lines of:
SELECT DISTINCT bg.name
FROM brand_group bg
WHERE bg.pid = (SELECT p.pid
FROM indicia_publisher ip
LEFT JOIN publisher p
ON ip.pid = p.pid
WHERE ip.cid = (SELECT country.cid
FROM country
WHERE country.name = 'Belgium') AND rownum <= 1);
ETA: I see that I misread your original SQL slightly and misinterpreted what you were after. It looks like you're after the p.pids with the highest count, so the following should do what you're after:
SELECT DISTINCT bg.name
FROM brand_group bg
WHERE bg.pid = (SELECT p.pid
FROM (SELECT p.pid,
COUNT(*) cnt,
MAX(COUNT(*)) OVER (PARTITION BY p.id) max_cnt
FROM indicia_publisher ip
LEFT JOIN publisher p
ON ip.pid = p.pid
WHERE ip.cid = (SELECT country.cid
FROM country
WHERE country.name = 'Belgium')
GROUP BY p.pid)
WHERE cnt = max_cnt
AND ROWNUM = 1);
If there are two or more different p.pids that have the highest count, the and rownum = 1 ensures only one will be picked (but it'll be random). May you want to use IN rather than = in the outer query's comparison, and that would remove the need for the rownum = 1 predicate.
is this Oracle, SQL Server? Oracle does not use left, Sql server does not have rownum. Do you expect one or more value to be return in subquery. it looks like more than 1. Then change BG.cid = () to ip.cid in (). Do you need the group in that subquery. You don't have count in that subquery.
I suggest you execute subquery one by one to find out what happens
Your original one has mixed of syntax (oracle/SqL server). I am going assume this is Oracle database
SELECT DISTINCT BG.name
FROM Brand_Group BG
WHERE BG.pid in
(SELECT P.pid
FROM Indicia_Publisher IP
WHERE
IP.pid=P.pid (+) and
(IP.cid=(SELECT Country.cid
FROM Country
WHERE Country.name='Belgium') AND ROWNUM<=1)
);

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.

SQL: Issue with WHERE Clause

SELECT DISTINCT Interests.Interest_name, Impressions.Count
FROM Interests
WHERE Vertical_name = 'Retail'
INNER JOIN Impressions ON Interests.Interest_Name = Impressions.Interest_Name;
The above query generates the error
Lookup Error - SQL Server Database Error: Incorrect syntax near the keyword 'Inner'.
If I remove the WHERE clause it works perfectly OK. I am not sure if there is an issue with the syntax?
WHERE condition needs to go after joins, try to move it to the end:
SELECT DISTINCT Interests.Interest_name,Impressions.Count FROM Interests
Inner Join Impressions ON Interests.Interest_Name = Impressions.Interest_Name
WHERE Vertical_name = 'Retail';
Well the Syntax is just wrong. You have to move the WHERE after your JOIN
For example:
SELECT DISTINCT Interests.Interest_name,Impressions.Count
FROM Interests
INNER JOIN Impressions
ON Interests.Interest_Name = Impressions.Interest_Name
WHERE Vertical_name = 'Retail';
If you tried to pre-filter your table Interests you can do that this way:
SELECT DISTINCT Interests.Interest_name,Impressions.Count
FROM (
SELECT *
FROM Interests
WHERE Vertical_name = 'Retail'
) as Interests
INNER JOIN Impressions
ON Interests.Interest_Name = Impressions.Interest_Name;
Just a hint after all. I would suggest you, to use aliases for every table. It will improve the reading and will save you if you need to rename a table.
The where goes after the from clause. And join is part of the from clause.
Your query would be easier to write and to read with aliases:
SELECT DISTINCT i.Interest_name, i.Count
FROM Interests i Inner Join
Impressions im
ON i.Interest_Name = im.Interest_Name;
WHERE Vertical_name = 'Retail';
If you don't need the DISTINCT, then you should remove it. It only hurts performance.
In fact, a better way to write this query is to use a correlated subquery:
SELECT DISTINCT i.Interest_name, i.Count
FROM Interests i
WHERE EXISTS (SELECT 1
FROM Impressions im
WHERE i.Interest_Name = im.Interest_Name
)
WHERE i.Vertical_name = 'Retail';
This assumes that Vertical_Name is in Interests. Otherwise, it would go in the subquery.

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)