I have a table Like below.
I want the product_id of Minimum, Maximum and Average cost products in a single query.
CREATE TABLE productlist(product_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
cost INT);
INSERT INTO productlist(cost)
VALUES('2450'),
('2200'),
('2580'),
('2405'),
('3500'),
('1500'),
('1800'),
('1520'),
('1740'),
('1940'),
('2940'),
('1250'),
('1290'),
('1390'),
('2900');
Output:
Min 12
Max 5
Avg 2093
I tried like one below but its not working.
SELECT product_id, MIN(cost) as mincost
FROM productlist
GROUP BY product_id
ORDER BY mincost ASC
LIMIT 0,1
UNION
SELECT product_id, max(cost) as maxcost
FROM productlist
GROUP BY product_id
ORDER BY maxcost DESC
LIMIT 0,1
How should I do this
select 'Min', product_id
from productlist
where cost = (select min(cost) from productlist)
UNION
select 'Max', product_id
from productlist
where cost = (select MAX(cost) from productlist)
UNION
select 'Avg', round(AVG(cost),0) as Avg
from productlist
select product_id, cost
from productlist where cost = (SELECT max(cost)from productlist)
union
select product_id, cost
from productlist where cost = (SELECT min(cost)from productlist)
union
select product_id, cost
from productlist where cost = (SELECT x.cost from productlist x, productlist y
GROUP BY x.cost
HAVING SUM(SIGN(1-SIGN(y.cost-x.cost))) = (COUNT(*)+1)/2)
This uses median, returns product id in every case
the output you want is not coming by the query you wrote
you need to try out this one for getting the required output
select 'Min', product_id
from productlist
where cost = (select min(cost) from productlist)
UNION
select 'Max', product_id
from productlist
where cost = (select MAX(cost) from productlist)
UNION
select 'Avg', floor(AVG(cost)) as Avg
from productlist
This answers your question exactly but it should be noted that it costs 3 table scans to find this data. Also, the example in the question suggests that the average value is truncated down to 2093 from 2093.67. It is perhaps better to replace this with round.
SQL Fiddle
SELECT concat('Min ', product_id)
FROM productlist
WHERE cost = (SELECT min(cost) from productlist)
UNION ALL
SELECT concat('Max ', product_id)
FROM productlist
WHERE cost = (SELECT max(cost) from productlist)
UNION ALL
SELECT concat('Avg ', truncate(avg(cost), 0))
FROM productlist
This is to select all the products
SELECT
max(cost), MIN(cost), AVG(cost)
FROM
productlist
GROUP BY
product_id
GROUP BY is not exactly required here. But seems like you are beginner, googling to will help you.
For your question try this.
SELECT
(select CONCAT(product_id, '-', cost) from productlist group by product_id order by cost DESC limit 1) as MAX,
(select CONCAT(product_id, '-', cost) from productlist group by product_id order by cost ASC limit 1) as MIN,
(select avg(cost) from productlist) as AVG
FROM
productlist limit 1
Related
I want to find name of that persons who worked most in a month. but the query doesn't returning max value from sum of value
I'm new in mysql
SELECT
x.name,
sec_to_time(MAX(x.sum_time)) maximum
FROM (
SELECT
name,
SUM(TIME_TO_SEC(ending_time) - TIME_TO_SEC(starting_time)) sum_time
FROM working_hours wh, employees
WHERE wh.employees_id = employees.id
AND project_id IS NOT NULL
GROUP BY employees_id
) x
GROUP BY x.name;
this is my query. i want to show just name of that persons who worked most in a month. but it returns all persons who worked in a month
Try making these changes to your query:
change name to MAX(name)
qualify employees_id with wh.employees_id
SELECT
x.name,
sec_to_time(MAX(x.sum_time)) maximum
FROM (
SELECT
MAX(name) AS name,
SUM(TIME_TO_SEC(ending_time) - TIME_TO_SEC(starting_time)) sum_time
FROM working_hours wh, employees
WHERE wh.employees_id = employees.id
AND project_id IS NOT NULL
GROUP BY wh.employees_id
) x
group by x.name;
Simply use Order by LIMIT -
SELECT X1.name, X1.maximum
FROM (SELECT name, SUM(TIME_TO_SEC(ending_time) - TIME_TO_SEC(starting_time)) maximum
FROM working_hours wh, employees
WHERE wh.employees_id=employees.id
GROUP BY name) X1
JOIN (SELECT SUM(TIME_TO_SEC(ending_time) - TIME_TO_SEC(starting_time)) sum_time
FROM working_hours wh, employees
WHERE wh.employees_id=employees.id
AND project_id is not null
GROUP BY employees_id
ORDER BY sum_time DESC
LIMIT 1) X2 ON X2.sum_time = X1.maximum;
I have a 80 tables and I want to filter who has the highest price among 80 tables. I plan on using this query:
SELECT id
FROM (SELECT id, price FROM T1 WHERE price = (SELECT MAX(price) FROM T1)
UNION
SELECT id, price FROM T2 WHERE price = (SELECT MAX(price) FROM T2)
UNION
SELECT id, price FROM T3 WHERE price = (SELECT MAX(price) FROM T3)
) AS M
ORDER BY price DESC
LIMIT 1
But I find it inefficient. Is there other way?
I think this would be a lot faster.
SELECT id, price FROM t1
UNION SELECT id, price FROM t2
UNION SELECT id, price FROM t3
ORDER BY price DESC
LIMIT 1
This question is an extension to this earlier question (not asked by me).
I have a table consisting of these fields:
id | date_from | date_to | price | priceName
--------------------------------------------------------
CK1 22-12-2012 29-12-2012 800 low
CK1 22-12-2012 29-12-2012 1200 medium
CK2 22-12-2012 29-12-2012 1400 high
CK2 22-12-2012 29-12-2012 1800 very high
CK2 22-12-2012 29-12-2012 2200 extortionate
How do I create a SQL select that groups the results by ID, DATE_FROM, DATE_TO and picks the lowest value from price and the priceName that is associated with the lowest price?
So the result would be
CK1 22-12-2012 29-12-2012 800 low
CK2 22-12-2012 29-12-2012 1400 high
From the previous question I can do:
select id, date_from, date_to, min(price)
from table
group by id, date_from, date_to
How do I extend this to only select the priceName that matches the min(price)? Grouping by priceName won't work because it does not constrain to the min(price).
You can use subquery.
Select Table.id,Date_from,date_to,MinPrice,PriceName
from
(select id, min(price) as MinPrice
from table
group by id) t1
INNER JOIN table ON t1.id=table.id and t1.MinPrice=table.Price
Group by id,Date_from,date_to,MinPrice,PriceName
Try this:
Select t.*,t1.priceName from (
select id, date_from, date_to, min(price)
from table
group by id, date_from, date_to) t
join table t1 on t.id =t1.id
and t.date_from =t1.date_from
and t.date_to =t1.date_to
and t.price =t1.price
One way would be to use the rank window function:
SELECT id, date_from, date_to, price, priceName
FROM (SELECT id, date_from, date_to, price, priceName,
RANK() OVER (PARTITION BY id, date_from, date_to
ORDER BY price ASC) AS rk
FROM mytable) t
WHERE rk = 1
Using CTE:
WITH cte (id, date_from, date_to, minprice) AS (
SELECT id, date_from, date_to, [minprice] = min(price)
FROM table_name
GROUP BY id, date_from, date_to)
SELECT
c.id, c.date_from, c.date_to, c.[minprice], t.priceName
FROM table_name t
JOIN cte c
ON t.id = c.id
AND t.date_from = c.date_to
AND t.data_to = c.date_to
I have 3 tables and my query is :
SELECT BRAND, AMOUNT FROM
(
SELECT BRAND, AMOUNT FROM SALES1
UNION
SELECT BRAND, AMOUNT FROM SALES2
UNION
SELECT BRAND, AMOUNT FROM SALES3
)
SALES 1 TABLE HAS BRAND: A AND AMOUNT: 50
SALES 3 TABLE HAS BRAND: A AND AMOUNT: 100
I want to get the amount 50 and disregard 100. I want to ask if is there any priority when using union?
If you want the first occurrence, you should use union all rather than union. This is important for performance reasons, because union does unnecessary duplicate elimination.
Then use the not exists clauses for each subquery:
(SELECT BRAND, AMOUNT
FROM SALES1
) UNION ALL
(SELECT BRAND, AMOUNT
FROM SALES2 s2
WHERE NOT EXISTS (SELECT 1 FROM SALES1 s1 WHERE s1.BRAND = s2.BRAND)
) UNION ALL
(SELECT BRAND, AMOUNT
FROM SALES3 s3
WHERE NOT EXISTS (SELECT 1 FROM SALES1 s1 WHERE s1.BRAND = s3.BRAND) AND
NOT EXISTS (SELECT 1 FROM SALES2 s2 WHERE s2.BRAND = s3.BRAND)
)
SELECT BRAND, AMOUNT
FROM
( SELECT BRAND, AMOUNT, 1 AS priority
FROM SALES1
UNION ALL
SELECT BRAND, AMOUNT, 2 AS priority
FROM SALES2
UNION ALL
SELECT BRAND, AMOUNT, 3 AS priority
FROM SALES3
)
ORDER BY priority
LIMIT 1;
you need a "where not exists"(or "not in" or a "left join") within your unions:
(SELECT BRAND, AMOUNT FROM SALES1 )
UNION
(SELECT BRAND, AMOUNT FROM SALES2)
UNION
(SELECT BRAND, AMOUNT FROM SALES3 where brand not in (SELECT BRAND FROM SALES1))
I have two SELECT statements that give the values "TotalSales" and "VendorPay_Com". I want to be able to subtract VendorPay_Com from TotalSales within the one MySQL statement to get the value "Outstanding_Funds" but I haven't found a reliable way to do so.
These are my two statements:
Query 1:
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold';
Query 2:
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
Any help on this matter would be greatly appreciated :)
You can do it as follows :
select (select ...) - (select ...)
In your example, simply :
select
(
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold'
)
-
(
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
) AS Outstanding_Funds
Try
SELECT TotalSales-VendorPay_Comm AS Outstanding_Funds
FROM
(SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold') t1,
(SELECT SUM(Amount) AS VendorPay_Comm
FROM (SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS Amount
FROM COMMISSION
WHERE Status = 'Paid') t0) t2
Here is sqlfiddle