QUESTION: I need to display the customers name and the total cost of the products they have ordered when they exceed over £10.
I cannot tell if it is because I am trying to use an inner join for three tables?
My attempt:
SELECT
DISTINCT Customer.custName,
SUM(Orders.quantity * Product.cost)
FROM
Customer,
Product
INNER JOIN Orders ON Product.productNo = Orders.productNo
WHERE
(Product.productNo = Orders.productNo)
AND (Orders.quantity * Product.cost > 10);
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax. Plus, use GROUP BY. And your JOIN conditions are not complete. So:
SELECT c.custName, SUM(o.quantity * p.cost)
FROM Customer c JOIN
Orders o
ON o.customerNo = c.customerNo JOIN
Product p
ON p.productNo = o.productNo
GROUP BY c.custName
HAVING SUM(o.quantity * p.cost) > 10;
Related
I created the alias NumDrums from the count operation. I would like to use this alias again to create another alias UnitTotal, a calculated column. When running the query I get the following error:
Error executing query:
#42S22Reference 'NumDrums' not supported (reference to group function)
Select
customers.CustCompanyName,
products.ProdUnNum,
customers.CustGenerator,
products.ProdID,
products.ProdSize,
products.ProdUnitName,
COUNT(*) as NumDrums,
(SELECT NumDrums) * products.ProdSize as UnitTotal
From
drums Inner Join
orders On drums.OrderID = orders.OrderID Inner Join
manifests On orders.ManifestID = manifests.ManifestID Inner Join
customers On drums.CustID = customers.CustID
And orders.CustID = customers.CustID Inner Join
products On drums.ProdID = products.ProdID
Group By
customers.CustCompanyName,products.ProdUnNum
Order by
customers.CustCompanyName
Just use COUNT(*) * products.ProdSize, thanks to user Thallius
I am running a query on a PHP page that will pull all records from one table, INNER JOIN with two other tables and then list all of the results. However on the second table I only want the most recent record.
Here is my query
SELECT * FROM wn_trailer
INNER JOIN (
SELECT id, trailer_id, trailer_status, trailer_assigned, MAX(last_update), trailer_lat, trailer_long
FROM wn_trailer_history
) AS th ON wn_trailer.id = th.trailer_id
INNER JOIN wn_trailer_status ON wn_trailer_status.id = th.trailer_status
INNER JOIN wn_users ON wn_users.id = th.trailer_assigned
ORDER BY trailer_number ASC
The query runs but returns only the first record.
You want an additional JOIN to bring in the data on the last update date. Also, your subquery needs a GROUP BY:
SELECT *
FROM wn_trailer t INNER JOIN
(SELECT trailer_id, MAX(last_update) as max_last_update
FROM wn_trailer_history
GROUP BY trailer_id
) tht
ON t.id = tht.trailer_id INNER JOIN
wn_trailer_history th
ON th.trailer_id = tht.trailer_id AND
th.last_update = tht.max_last_update INNER JOIN
wn_trailer_status ts
ON ts.id = th.trailer_status INNER JOIN
wn_users u
ON u.id = th.trailer_assigned
ORDER BY trailer_number ASC;
I also added table aliases so the query is easier to write and to read.
This is something I'm trying to get my head around... I have three tables like this:
Practice
* PracticeID
* PracticeName
Group
* GroupID
* Sales
* Salaries
* Overheads
Values
* PracticeID
* GroupID
* Income
* Expense
What I am looking to do is prepare a view to sum up the income and expenses in Values by the group names in the Group table. I can get as far as a row by row summary, but I'm having the issue on how to include the group clause in the code I currently have, which is below:
SELECT Practice.PracticeName, Group.Groupname, Values.Income, Values.Expenses
FROM values INNER JOIN
Practice ON values.PracticeID = Practice.PracticeID INNER JOIN
Group ON Values.NominalGroupID = Group.GroupID
try this:
SELECT Practice.PracticeName, Group.Groupname, SUM(Values.Income) as SumIncome, SUM(Values.Expenses ) as SumExpences
FROM values INNER JOIN
Practice ON values.PracticeID = Practice.PracticeID INNER JOIN
Group ON Values.NominalGroupID = Group.GroupID
Group By Group.Groupname
Your table definition does not really include all the columns you used in your example so I'm not sure if that's what you are looking for:
SELECT Group.Groupname
,SUM(Values.Income) as Income
,SUM(Values.Expenses ) as Expenses
FROM Group
INNER JOIN Value ON Values.GroupID = Group.GroupID
Group By Group.Groupname
I will try to explain things as much as I can.
I have following query to fetch records from different tables.
SELECT
p.p_name,
p.id,
cat.cat_name,
p.property_type,
p.p_type,
p.address,
c.client_name,
p.price,
GROUP_CONCAT(pr.price) AS c_price,
pd.land_area,
pd.land_area_rp,
p.tagline,
p.map_location,
r.id,
p.status,
co.country_name,
p.`show`,
u.name,
p.created_date,
p.updated_dt,
o.type_id,
p.furnished,
p.expiry_date
FROM
property p
LEFT OUTER JOIN region AS r
ON p.district_id = r.id
LEFT OUTER JOIN country AS co
ON p.country_id = co.country_id
LEFT OUTER JOIN property_category AS cat
ON p.cat_id = cat.id
LEFT OUTER JOIN property_area_details AS pd
ON p.id = pd.property_id
LEFT OUTER JOIN sc_clients AS c
ON p.client_id = c.client_id
LEFT OUTER JOIN admin AS u
ON p.adminid = u.id
LEFT OUTER JOIN sc_property_orientation_type AS o
ON p.orientation_type = o.type_id
LEFT OUTER JOIN property_amenities_details AS pad
ON p.id = pad.property_id
LEFT OUTER JOIN sc_commercial_property_price AS pr
ON p.id = pr.property_id
WHERE p.id > 0
AND (
p.created_date > DATE_SUB(NOW(), INTERVAL 1 YEAR)
OR p.updated_dt > DATE_SUB(NOW(), INTERVAL 1 YEAR)
)
AND p.p_type = 'sale'
everything works fine if I exclude GROUP_CONCAT(pr.price) AS c_price, from above query. But when I include this it just gives one result. My intention to use group concat above is to fetch comma separated price from table sc_commercial_property_price that matches the property id in this case p.id. If the records for property exist in sc_commercial_property_price then fetch them in comma separated form along with other records. If not it should return blank. What m I doing wrong here?
I will try to explain again if my problem is not clear. Thanks in advance
The GROUP_CONCAT is an aggregation function. When you include it, you are telling SQL that there is an aggregation. Without a GROUP BY, only one row is returns, as in:
select count(*)
from table
The query that you have is acceptable syntax in MySQL but not in any other database. The query does not automatically group by the columns with no functions. Instead, it returns an arbitrary value. You could imagine a function ANY, so you query is:
select any(p.p_name) as p_num, any(p.tagline) as tagline, . . .
To fix this, put all your current variables in a group by clause:
GROUP BY
p.p_name,
p.id,
cat.cat_name,
p.property_type,
p.p_type,
p.address,
c.client_name,
p.price,
pd.land_area,
pd.land_area_rp,
p.tagline,
p.map_location,
r.id,
p.status,
co.country_name,
p.`show`,
u.name,
p.created_date,
p.updated_dt,
o.type_id,
p.furnished,
p.expiry_date
Most people who write SQL think it is good form to include all the group by variables in the group by clause, even though MySQL does not necessarily require this.
Add GROUP BY clause enumerating whatever you intend to have separate rows for. What happens now is that it picks some value for each result column and group_concats every pr.price.
I am trying to retrieve a list of products which have been updated, the table contains multiple updates of the products as it records the price changes.
I need to get the latest price changes for all products, but only return the the last update. I have the below code so far, but it only returns the very last update and only 1 product.
SELECT dbo.twProducts.title, dbo.LowestPrices.productAsin, dbo.twProducts.sku,
dbo.LowestPrices.tweAmzPrice, dbo.LowestPrices.price, dbo.LowestPrices.priceDate
FROM dbo.aboProducts INNER JOIN
dbo.LowestPrices ON dbo.aboProducts.asin = dbo.LowestPrices.productAsin
INNER JOIN dbo.twProducts ON dbo.aboProducts.sku = dbo.twProducts.sku
WHERE (dbo.LowestPrices.priceDate =
(SELECT MAX(priceDate) AS Expr1
FROM dbo.LowestPrices AS LowestPrices_1))
I hope this makes sense, i am not sure if i have explained it in a way thats easy to understand.
Any questions please feel free to ask.
The easiest would be to use a CTE with ROW_NUMBER function:
WITH CTE AS
(
SELECT dbo.twProducts.title, dbo.LowestPrices.productAsin, dbo.twProducts.sku,
dbo.LowestPrices.tweAmzPrice, dbo.LowestPrices.price, dbo.LowestPrices.priceDate,
RN = ROW_NUMBER()OVER( PARTITION BY productAsin ORDER BY priceDate DESC)
FROM dbo.aboProducts INNER JOIN
dbo.LowestPrices ON dbo.aboProducts.asin = dbo.LowestPrices.productAsin
INNER JOIN dbo.twProducts ON dbo.aboProducts.sku = dbo.twProducts.sku
)
SELECT * FROM CTE WHERE RN = 1
I think the adjustment to the query you are looking for is to join your subquery rather than just matching on the Date.
SELECT dbo.twProducts.title, dbo.LowestPrices.productAsin, dbo.twProducts.sku,
dbo.LowestPrices.tweAmzPrice, dbo.LowestPrices.price, dbo.LowestPrices.priceDate
FROM dbo.aboProducts INNER JOIN
dbo.LowestPrices ON dbo.aboProducts.asin = dbo.LowestPrices.productAsin
INNER JOIN dbo.twProducts ON dbo.aboProducts.sku = dbo.twProducts.sku
WHERE dbo.LowestPrices.priceDate IN
(SELECT MAX(LowestPrices_1.priceDate)
FROM dbo.LowestPrices AS LowestPrices_1
WHERE dbo.LowestPrices.productAsin = LowestPrices_1.productAsin)
This will match on the max(priceDate) for each product