Join 2 tables and calculate the median in the same query - mysql

I need to SELECT how many orders (table1) the employernumber (in both tables) with the median payment (table2) has and what is the "numberoforders".
Thanks!
I tried this for merging:
SELECT *
FROM ORDERS
JOIN PAYMENTS
USING (employernumber)
And this as MEDIAN
Select* from
(
select employernumber, amounts, row_number() over (order by amounts desc) as desc_amounts,
row_number() over (order by amount asc) as asc_amount
from payments
) as median
where asc_amount in(desc_amounts,desc_amounts+1,desc_amounts)
JOIN payments
using (employernumber)

Related

how do I join two tables and then find the find the top 5 custmer_names based on sales_amount and grouped by custmer name

Basically I want the top 5 custmer_name with maximum sales_amount grouped by custmer_name
with results as (
SELECT custmer_name, sales_amount from sales.customers inner join sales.transactions
on sales.customers.customer_code = sales.transactions.customer_code
)
select *, dense_rank() over(partition by custmer_name order by sales_amount desc) as ranking from results
customers table
transactions table
Result after join
You should compute the dense rank inside the CTE or subquery, and the filter on it outside:
WITH results AS (
SELECT c.custmer_name, t.sales_amount,
DENSE_RAN() OVER (PARTITION BY c.custmer_name
ORDER BY t.sales_amount DESC) AS ranking
FROM customers c
INNER JOIN transactions t
ON c.customer_code = t.customer_code
)
SELECT *
FROM results
WHERE ranking <= 5;

How can i get the max-value out of a subquery?

so in MySQL I have the task to filter out those customer names with the max overall revenue. I used the following query:
SELECT name
FROM
(SELECT name, SUM(sale_price) as revenue
FROM customer
INNER JOIN order USING(customerID)
INNER JOIN orderdetails USING(ordernumber)
GROUP BY name) as revenues
WHERE revenues.revenue = (SELECT MAX(revenue)
FROM revenues);
Now I understand, I cannot reference the alias of the subquery in my WHERE-clause. But how can I filter out only those names with the max value without more or less writing the same query as a filter again?
Thank you!
I'm using version 8.0.20
WITH
revenues AS (SELECT name,
DENSE_RANK() OVER (ORDER BY SUM(sale_price) DESC) dr
FROM customer
INNER JOIN order USING (customerID)
INNER JOIN orderdetails USING (ordernumber)
GROUP BY name),
SELECT name
FROM revenues
WHERE dr = 1

MySQL - Group and total, but return all rows in each group

I'm trying to write a query that finds each time the same person occurs in my table between a specific date range. It then groups this person and totals their spending for a specific range. If their spending habits are greater than X amount, then return each and every row for this person between date range specified. Not just the grouped total amount. This is what I have so far:
SELECT member_id,
SUM(amount) AS total
FROM `sold_items`
GROUP BY member_id
HAVING total > 50
This is retrieving the correct total and returning members spending over $50, but not each and every row. Just the total for each member and their grand total. I'm currently querying the whole table, I didn't add in the date ranges yet.
JOIN this subquery with the original table:
SELECT si1.*
FROM sold_items AS si1
JOIN (SELECT member_id
FROM sold_items
GROUP BY member_id
HAVING SUM(amount) > 50) AS si2
ON si1.member_id = si2.member_id
The general rule is that the subquery groups by the same column(s) that it's selecting, and then you join that with the original query using the same columns.
SELECT member_id, amount
FROM sold_items si
INNER JOIN (SELECT member_id,
SUM(amount) AS total
FROM `sold_items`
GROUP BY member_id
HAVING total > 50) spenders USING (member_id)
The query you have already built can be used as a temporary table to join with. if member_id is not an index on the table, this will become slow with scale.
The word spenders is a table alias, you can use any valid alias in its stead.
There are a few syntaxes that will get the result you are looking, here is one using an inner join to ensure that all rows returned have a member_id in the list returned by the group by and that the total is repeated for each a certain member has:
SELECT si.*, gb.total from sold_items as si, (SELECT member_id as mid,
SUM(amount) AS total
FROM `sold_items`
GROUP BY member_id
HAVING total > 50) as gb where gb.mid=si.member_id;
I think that this might help:
SELECT
member_id,
SUM(amount) AS amount_value,
'TOTAL' as amount_type
FROM
`sold_items`
GROUP BY
member_id
HAVING
SUM(amount) > 50
UNION ALL
SELECT
member_id,
amount AS amount_value,
'DETAILED' as amount_type
FROM
`sold_items`
INNER JOIN
(
SELECT
A.member_id,
SUM(amount) AS total
FROM
`sold_items` A
GROUP BY
member_id
HAVING
total <= 50
) AS A
ON `sold_items`.member_id = A.member_id
Results of the above query should be like the following:
member_id amount_value amount_type
==========================================
1 55 TOTAL
2 10 DETAILED
2 15 DETAILED
2 10 DETAILED
so the column amount_type would distinguish the two specific member groups
You could do subquery with EXISTS as an alternative:
select *
from sold_items t1
where exists (
select * from sold_items t2
where t1.member_id=t2.member_id
group by member_id
having sum(amount)>50
)
ref: http://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
In case you need to group by multiple columns, you can use a composite identifier with concatenate in combination with a group by subquery
select id, key, language, group
from translation
--query all key-language entries by composite identifier...
where concat(key, '_', language) in (
--by lookup of all key-language combinations...
select concat(key, '_', language)
from translation
group by key, language
--that occur more than once
having count(*) > 1
)

SQL - Does row match max of sums

I am getting a little tripped up with a SQL query. Here is some background.
Schema:
Product(pid, price, color),
Order(cid, pid, quantity),
Customer(cid, name, age)
I want to get the pid of the most ordered product (greatest quantity).
I have managed to determine the max value with:
Select Max(total)
From (Select Sum(quantity) as total
From Orders Group By pid) as Totals
but I am getting stuck trying to match which products are in this subquery. Here is what I have tried:
Select pid, SUM(quantity) as q
From Orders
Where q in (
Select Max(total)
From (Select Sum(quantity) as total
From Orders
Group By pid) as Totals
)
Group By pid
This says that q is an unknown column.
Any suggestions on how I could do this or do it better?
you can do a JOIN along with GROUP BY like
select p.*
from product p
join
(select pid from Order
group by pid having quantity = max(quantity)
) tab on p.pid = tab.pid;
In your posted query it's erroring q is an unknown column cause q is a column alias which you are trying to use in WHERE condition; which is not allowed.
You should be able to simply include the PID in the original query because you are grouping on it. Then ORDER BY and and get only the top result using LIMIT 1.
SELECT
pid
,Sum(quantity) as total
FROM
Orders
GROUP BY
pid
ORDER BY
Sum(quantity)
LIMIT 1
Here's one way you can do it using a subquery with limit:
select o.pid, sum(o.quantity)
from `order` o
group by o.pid
having sum(o.quantity) =
(
select sum(quantity)
from `order`
group by pid
order by sum(quantity) desc
limit 1
)
SQL Fiddle Demo
If you want only one most ordered product, then Karl's answer is fine. If you want all that have the same quantity, then:
select pid, sum(quantity) as quantity
from orders o
group by pid
having sum(quantity) = (select max(quantity)
from (select sum(quantity) as quantity
from orders o
group by pid
) q
);

MySQL - select multiple maximum values

I have a table called order which contains columns id, user_id, price. I would like to select each user's most expensive order - the order for which that user paid the highest price. I want to select order.user_id and order.price in the same query.
select user_id, max(price) from `order` group by user_id
SELECT order.user_id, A.price
FROM `order`
LEFT JOIN
(SELECT user_id, price FROM `order` ORDER BY price DESC) A USING (user_id)