SQL get max in table with COUNT - oracle-sqldeveloper

SELECT a.FirstName, a.LastName, Count(cai.ArtistID)
FROM Artist a
JOIN CUSTOMER_ARTIST_INT cai ON(a.ArtistID=cai.ArtistID)
GROUP BY a.FirstName, a.LastName
Gives me an output of
FirstName LastName COUNT(CAI.ArtistID)
Luke Skywalker 2
Han Solo 7
Darth Vader 3
However, my query must only give me the one with the highest Count thus the output should be:
FirstName LastName COUNT(CAI.ArtistID)
Han Solo 7
I know I have to put the MAX function but i have no idea how.

you can use top 1 order by desc as below
SELECT top (1) a.FirstName, a.LastName, Count(cai.ArtistID)
FROM Artist a
JOIN CUSTOMER_ARTIST_INT cai ON (a.ArtistID=cai.ArtistID)
GROUP BY a.FirstName, a.LastName
order by count(cai.Artistid) desc
If you are looking for certain category you might require to use row_number

Related

Is it possible to joining multiple row

I am looking for a way to join two rows with same value (promo code in my case). So for example, I have a table:
ID PROMO_CODE PROMO_NAME DESCRIPTION LANGUAGE
1 PC123 ABC Desc in English ENG
2 PC123 CBA Desc in Español ESP
and I want the result like:
ID PROMO_CODE PROMO_NAME_ENG PROMO_NAME_ESP DESCRIPTION_ENG DESCRIPTION_ESP
1 PC123 ABC CBA Desc in English Desc in Español
Any help will be appreciate
Join on PROMO_CODE:
select
a.ID,
a.PROMO_CODE,
a.PROMO_NAME as PROMO_NAME_ENG,
b.PROMO_NAME as PROMO_NAME_ESP,
a.DESCRIPTION as DESCRIPTION_ENG,
b.DESCRIPTION as DESCRIPTION_ESP
from mytable a
left join mytable b on b.PROMO_CODE = a.PROMO_CODE
and b.LANGUAGE = 'ESP'
where a.LANGUAGE = 'ENG'
Using a left join guarantees the ENG data even if the ESP data doesn't exist, which seems possible due to ENG's ID being in the output, but not ESP's ID

Query to return multiple MAX values with HAVING clause

I want to write a query that will return the name of students who did the most projects with the count of the project. I want the query to return a table like this:
student_name
max_project_count
John Doe
2
Anna Do
2
This is the code I have so far but it's only giving me the 2 column names student_name and count, but not the result.
SELECT s.student_name, COUNT(student_name)
FROM student s
GROUP BY student_name
HAVING COUNT(student_name) = (
SELECT MAX(count)
FROM (SELECT s.student_name, COUNT(*) AS count
FROM student_project k, student s
WHERE s.student_id = k.student_id
GROUP BY student_name) AS foo)
Result I have right now:
student_name
max_project_count
These are the tables I have in my database:
student
student_id
student_name
jd123
John Doe
ad456
Anna Do
js678
Jess Smith
dk789
Daniel Kim
school_project
project_id
project_name
math_1023
Math Comp.
sci_9872
Science Comp.
student_project
student_id
project_id
jd123
math_1023
ad456
math_1023
jd123
sci_9872
ad456
sci_9872
js678
sci_9872
dk789
sci_9872
with projects as (
Select student_id, count(*) as pcount from student_project group by 1),
max_proj as (
Select max(pcount) as max_project_count from projects)
Select
student_name, max_project_count
from student s,projects p,max_proj m
where
s.student_id=p.student_id and pcount=max_project_count

How to simplify a join of 2 tables in HIVE and count values

I have two tables in HIVE, "orders" and "customers". I want to get top n user names of users who placed most orders (in status "CLOSED"). Orders table has key order_customer_id, column order_status and customers has key customer_id and name consists of 2 columns customer_fname and customer_lname.
ORDERS
order_customer_id, order_status
1,CLOSED
2,CLOSED
3,INPROGRESS
1,INPROGRESS
1,CLOSED
2,CLOSED
CUSTOMERS
customer_id, customer_fname, customer_lname
1,Mickey, Mouse
2,Henry, Ford
3,John, Doe
I tried this code:
select c.customer_id, count(o.order_customer_id) as COUNT, concat(c.customer_fname," ",c.customer_lname) as FULLNAME from customers c join orders o on c.customer_id=o.order_customer_id where o.order_status='CLOSED' group by c.customer_id,FULLNAME order by COUNT desc limit 10;
this does not work - returns error.
I was able to get the result by first creating a 3rd table:
create table id_sum as select o.order_customer_id,count(o.order_id) as COUNT from orders o join customers c on c.customer_id=o.order_customer_id where order_status='CLOSED' group by o.order_customer_id;
1833 6
5493 5
1363 5
1687 5
569 4
1764 4
1345 4
Then I joined the tables:
select s.*,concat(c.customer_fname," " ,c.customer_lname) from id_sum s join customers c on s.order_customer_id = c.customer_id order by count desc limit 20;
This resulted in desired output:
customer_id, order_count, full_name
1833 6 Ronald Smith
5493 5 Mary Cochran
1363 5 Kathy Rios
1687 5 Jerry Ellis
569 4 Mary Frye
1764 4 Megan Davila
1345 4 Adam Wilson
Is there a way how to write it in one command or more effectively?
The subquery with alias sq creates a relation with two columns order_count and customer_id calculating for each customer_id the total number of orders. This is then joined with the CUSTOMERS table. The result is sorted descending and limited to (the top) 10 rows.
SELECT c.customer_id, sq.order_count, concat(c.customer_fname," " ,c.customer_lname) as full_name
FROM CUSTOMERS c JOIN (
SELECT COUNT(*) as order_count, order_customer_id FROM ORDERS
WHERE order_status = 'CLOSED'
GROUP BY order_customer_id
) sq on c.customer_id = sq.order_customer_id
ORDER BY sq.order_count desc LIMIT 10
;
The idea is to use a subquery instead of a third table.

Biggest sale of every employee on Northwind?

I'm trying to list the biggest sale of each employee on Northwind database, and so far the best I could do is this;
select top (select count(EmployeeID) from Employees)
max(Quantity*OrderDetails.UnitPrice) TotalSale, FirstName+' '+LastName Name, ProductName from Orders
left join OrderDetails
on
OrderDetails.OrderID=Orders.OrderID
left join Employees
on
Orders.EmployeeID=Employees.EmployeeID
left join Products
on
OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName, ProductName
order by TotalSale desc
But even though I used the group by I get repeated records;
TotalSale Name ProductName
15810,00 Andrew Fuller Côte de Blaye
15810,00 Nancy Davolio Côte de Blaye
10540,00 Robert King Côte de Blaye
10540,00 Anne Dodsworth Côte de Blaye
10540,00 Margaret Peacock Côte de Blaye
9903,20 Janet Leverling Thüringer Rostbratwurst
8432,00 Steven Buchanan Côte de Blaye
7905,00 Janet Leverling Côte de Blaye
7427,40 Andrew Fuller Thüringer Rostbratwurst
Warning: Null value is eliminated by an aggregate or other SET operation.
(9 row(s) affected)
So I have 9 employees and I used top function for that but the employees are not unique, I also tried to use distinct function but it didn't work either.
So I would appreciate a hand please!
Your issue is that you also group by productname. So you will get max sales per employee and per product name.
What you can do is, drop the product name in group by, in this case you will see max total sales only per employee.
select max(Quantity*OrderDetails.UnitPrice) TotalSale, FirstName+' '+LastName Name
from Orders
left join [Order Details] as OrderDetails on OrderDetails.OrderID=Orders.OrderID
left join Employees on Orders.EmployeeID=Employees.EmployeeID
left join Products on OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName
order by TotalSale desc
In case you want to see the product name as well, you can encapsulate your query in a subquery and create a rownum based on employee name and order by total sales. You can select rows with rownum 1 in the outer query. Use rank function in case you need to show all occurances of product names.
SELECT TotalSale, Name, ProductName
FROM
(
select max(Quantity*OrderDetails.UnitPrice) TotalSale
,FirstName + ' ' + LastName Name
,ProductName
,Rnk = Rank() OVER(PARTITION BY Employees.EmployeeId ORDER BY MAX(Quantity*OrderDetails.UnitPrice) DESC)
from Orders
left join [Order Details] as OrderDetails on OrderDetails.OrderID=Orders.OrderID
left join Employees on Orders.EmployeeID=Employees.EmployeeID
left join Products on OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName, Employees.EmployeeId, ProductName
) as sub
where sub.Rnk = 1
order by Name

How to get firstname and second maximum salary of the record using subqueries?

I'm new to oracle. I have to get firstname and second maximum salary of the record from the table using sub-queries.
I've tried below query:
select max(salary)
from employees
where salary > (select max(salary)
from empoloyees);
this query used to get second max salary from the table. Now I have to get firstname of the second salary record.
firstname salary
-------------------
mani 45666
vijay 50000
sanjay 65000
SELECT firstname, salary FROM
(SELECT * FROM employees ORDER BY salary DESC)
WHERE rownum = 2;
The inner SELECT sorts the table by salary, in order from greatest to least (hence DESC).
The outer SELECT takes the two fields you want from row 2 (which holds the second highest salary) of the sorted table.
you can use dense_rank for this.
select firstname, salary
from (select /*+ first_rows(2) */ firstname, salary,
dense_rank() Over (order by salary desc) r
from employees)
where r = 2;
the first_rows hint is there as to help it use an index (index on (salary) or (salary, firstname).
This may return > 1 row if 2 people happen to share the same salary (you can add and rownum = 1 to pick just one at random).
Try this out
SELECT * FROM EMP WHERE SAL >=(SELECT MAX (SAL) FROM EMP WHERE SAL < (SELECT MAX(SAL) FROM EMP WHERE SAL <(SELECT MAX(SAL) FROM EMP))) AND ROWNUM < 4 ORDER BY SAL