oracle display customer who purchased most cars WITHOUT analytic functions - sql

I'm currently trying to answer the following question:
Display the name of the customer who has purchased the most cars from Archie’s Luxury Motors.
Tables I'm working with:
Customer
(custID, name, DOB, streetAddress, suburb, postcode,
gender, phoneNo, email, type)
SalesTransaction
(VIN, custID, agentID, dateOfSale, agreedPrice)
My query
select *
from (
select customer.name
from customer, salestransaction
where customer.custID = salestransaction.custID
group by (customer.name), salestransaction.custID
order by count(*) desc
)
where rownum=1;
Now I've found out that I cannot use analytic functions (rownum & rank)
How would I go about doing this with using pure transactional SQL only?

You could use MAX and COUNT aggregate functions:
WITH data AS
(SELECT c.name cust_nm,
COUNT(*) cnt
FROM customer c,
salestransaction s
WHERE c.custID = s.custID
GROUP BY c.NAME
ORDER BY cnt DESC
)
SELECT cust_nm FROM data WHERE cnt =
(SELECT MAX(cnt) FROM DATA
);
An example from EMP and DEPT table:
SQL> WITH data AS
2 (SELECT e.deptno,
3 COUNT(*) cnt
4 FROM emp e,
5 dept d
6 WHERE e.deptno = d.deptno
7 GROUP BY e.deptno
8 ORDER BY cnt DESC
9 )
10 SELECT deptno FROM DATA WHERE cnt =
11 (SELECT MAX(cnt) FROM DATA
12 );
DEPTNO
----------
30
SQL>

Related

Finding the max after Counting with Specific Conditions

I am trying to find the department with the maximum amount of null assigned.
Here is the table Class:
Dept Assigned
CSCE
CSCE
ELEG 4
ELEG
MATH
ELEG
So since CSCE and ELEG have the largest amount of null assigned, I want to output.
Dept Max(Count)
CSCE 2
ELEG 2
Here is what I have:
Select Dept, Max(Countt)
from (Select Dept, Count(Dept) as Countt
from Class
where assigned is null group by Dept
);
However, it is outputting the count for all the Dept including Math. How can I fix that?
I am using Oracle.
You can use window functions for this:
select d.Dept, cnt
from (select c.Dept, Count(*) as cnt,
rank() over (order by count(*) desc) as seqnum
from Class c
where c.assigned is null
group by c.Dept
) d
where seqnum = 1;
One other way:
select count(*), dept from table
where assigned is null
group by dept
having count(*) = (select max(c) from (select count(*) as c from table
where assigned is null
group by dept) as t)

SQL oracle: Need to display a query.

so i have 3 tables linked together named office, employee, and dependent.
office: Oid (PK), officeName
employee: EID(PK), Fname, Lname, JobTitle, Salary, DOH, Gender, DOB, OID(FK1), Supervisor(FK2)
Dependent: DID(PK), Fname, Lname, Gender, EID(FK1)
Here is the link to the picture of the tables:
http://classweb2.mccombs.utexas.edu/mis325/class/hw/hw12a.jpg
I need to display concatenated name and EID of 5 employees with the largest number of dependents, if there is a tie for the five largest, then I need to display all of the tying employees.
I am confused on how to begin. please help :)
thank you in advance
Just break down the problem:
How many dependents an EID has:
SELECT EID, COUNT(*) AS C
FROM Dependent
GROUP BY EID
Add a rank
SELECT EID, C, RANK() OVER (ORDER BY C DESC)
FROM (
SELECT EID, COUNT(*) AS C
FROM Dependent
GROUP BY EID
) S
We want the first 5
SELECT EID
FROM (
SELECT EID, C, RANK() OVER (ORDER BY C DESC) AS R
FROM (
SELECT EID, COUNT(*) AS C
FROM Dependent
GROUP BY EID
) S
) S2
WHERE R <= 5
Now ask for what you want:
SELECT * -- or whatever
FROM Employee
WHERE EID IN (
SELECT EID
FROM (
SELECT EID, C, RANK() OVER (ORDER BY C DESC) AS R
FROM (
SELECT EID, COUNT(*) AS C
FROM Dependent
GROUP BY EID
) S
) S2
WHERE R <=5
) S3
I suggest you run each step and make sure it gives you the expected results.
Ummm I would try something like this:
Select TOP 5
a.FNAME,
a.LNAME,
a.EID,
Count(b.EID) as Dependents
FROM employee a
LEFT JOIN dependent b on a.EID = b.EID
group by 1,2,3 order by Dependents desc

Pivoting in sql [duplicate]

This question already has answers here:
SQL Server: Examples of PIVOTing String data
(7 answers)
Closed 7 years ago.
i have sql table with data as given below
emp id empname dept
------- ---- ------
1 a Hr
2 b Hr
3 c Tech
4 d Hr
5 e Admin
7 f Tech
8 g Admin
Now i want to pivot the above table get the result like this
Hr Tech Admin
----- ----- -----
Empname a c e
Empname b f g
Empname d
I am just wondering is this even possible using pivoting in sql or there is any other mean to achieve this
You can use conditional aggregation with ROW_NUMBER:
SQL Fiddle
WITH Cte AS(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY dept ORDER BY empid)
FROM tbl
)
SELECT
[Hr] = MAX(CASE WHEN dept = 'Hr' THEN empname END),
[Tech] = MAX(CASE WHEN dept = 'Tech' THEN empname END),
[Admin] = MAX(CASE WHEN dept = 'Admin' THEN empname END)
FROM cte
GROUP BY rn
Here is the PIVOT version:
SQL Fiddle
;WITH Cte AS(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY dept ORDER BY empid)
FROM tbl
)
SELECT *
FROM(
SELECT
dept, MAX(empname) AS empname,RN
FROM Cte
GROUP BY dept, RN
)t
PIVOT
(
MAX(empname)
FOR dept in ([Hr], [Tech], [Admin])
)piv
This type of manipulation is often best done in the presentation layer. It appears that you want three different lists in the columns, so the rows are not really related to each other.
That said, you can do this in SQL, but you need to get a "list position" for each column. For that, use row_number():
select h.empname as hr, t.empname as tech, a.empname as admin
from (select empname, row_number() over (order by empname) as seqnum
from table
where dept = 'Hr'
) h full outer join
(select empname, row_number() over (order by empname) as seqnum
from table
where dept = 'Tech'
) t
on t.seqnum = h.seqnum full outer join
(select empname, row_number() over (order by empname) as seqnum
from table
where dept = 'Admin'
) a
on a.seqnum in (h.seqnum, t.seqnum)

Finding department having maximum number of employee

I have a table employee
id name dept
1 bucky shp
2 name shp
3 other mrk
How can i get the name of the department(s) having maximum number of employees ? ..
I need result
dept
--------
shp
SELECT cnt,deptno FROM (
SELECT rank() OVER (ORDER BY cnt desc) AS rnk,cnt,deptno from
(SELECT COUNT(*) cnt, DEPTNO FROM EMP
GROUP BY deptno))
WHERE rnk = 1;
Assuming you are using SQL Server and each record representing an employee. So you can use window function to get the result
WITH C AS (
SELECT RANK() OVER (ORDER BY dept) Rnk
,name
,dept
FROM table
)
SELECT TOP 1 dept FROM
(SELECT COUNT(Rnk) cnt, dept FROM C GROUP BY dept) t
ORDER BY cnt DESC
With common table expressions, count the number of rows per department, then find the biggest count, then use that to select the biggest department.
WITH depts(dept, size) AS (
SELECT dept, COUNT(*) FROM employee GROUP BY dept
), biggest(size) AS (
SELECT MAX(size) FROM depts
)
SELECT dept FROM depts, biggest WHERE depts.size = biggest.size
Based on one of the answer, Let me try to explain step by step
First of all we need to get the employee count department wise. So the firstly innermost query will run
select count(*) cnt, deptno from scott.emp group by deptno
This will give result as
Now out of this we have to get the one which is having max. employee i.e. department 30.
Also please note there are chances that 2 departments have same number of employees
The second level of query is
select rank() over (order by cnt desc) as rnk,cnt,deptno from
(
select count(*) cnt, deptno from scott.emp group by deptno
)
Now we have assigned ranking to each department
Now to select rank 1 out of it. we have a simplest outer query
select * from
(
select rank() over (order by cnt desc) as rnk,cnt,deptno from
(
select count(*) cnt, deptno from scott.emp group by deptno
)
)
where rnk=1
So we have the final result where we got the department which has the maximum employees. If we want the minimum one we have to include the department table as there are chances there is a department which has no employees which will not get listed in this table
You can ignore the scott in scott.emp as that is the table owner.
The above SQL can be practised at Practise SQL online

Get MAX value of count of each dept after group by clause on dept and grade

My query gets count of employee for each dept for each grade .
select dept , grade , count(1) CNT
from mytable
group by dept , grade
order by dept , cnt desc;
now i need from that the grades getting max count of each dept .
output should be
dept grades MAX(count)
how can i do that?
Thanks
The best way to do this is using the row_number() function:
select dept, grade, cnt
from (select dept, grade, count(*) as cnt,
row_number() over (partition by dept order by count(*) desc) as seqnum
from mytable t
group by dept, grade
) t
where seqnum = 1