select Customer_Name from Customer where Customer_Id IN
(select distinct Customer.Customer_Id from Customer join Toy_Rental on Toy_Rental.Customer_ID=Customer.Customer_Id
order by Toy_Rental.Total_Amount desc
fetch next 2 rows only);
There's no FETCH clause in 11g; it is available in 12c.
See if this helps:
select a.Customer_Name
from Customer a
where a.Customer_Id IN (select x.customer_id
from (select c.Customer_Id
from Customer c join Toy_Rental t on t.customer_id = c.customer_id
order by t.total_amount desc
) x
where rownum <= 2
)
Alternatively:
with cust as
(select c.customer_id
row_number() over (order by t.total_amount desc) rn
from customer c join toy_rental t on t.customer_id = c.customer_id
)
select a.customer_name
from customer a join cust x on x.customer_id = a.customer_id
where x.rn <= 2
Related
I can not execute this code on Oracle, the error shows:
"ORA-00979: not a GROUP BY expression"
However, I was able to run it successfully on MySQL.
How does this happen?
SELECT CONCAT(i.lname, i.fname) AS inst_name,
CONCAT(s.lname, s.fname) AS stu_name,
t.avg_grade AS stu_avg_grade
FROM(
SELECT instructor_id, student_id, AVG(grade) as avg_grade, RANK() OVER(PARTITION BY instructor_id ORDER BY grade DESC) AS rk
FROM grade
GROUP BY 1,2) t
JOIN instructor i
ON t.instructor_id = i.instructor_id
JOIN student s
ON s.student_id = t.student_id
WHERE t.rk = 1
ORDER BY 3 DESC
You can't use ordinals like GROUP BY 1,2 in Oracle. In addition, the ORDER BY grade clause inside your RANK() function has a problem. Keep in mind that analytic functions evaluate after the GROUP BY aggregation, so grade is no longer available. Here is a version which should work without error:
SELECT CONCAT(i.lname, i.fname) AS inst_name,
CONCAT(s.lname, s.fname) AS stu_name,
t.avg_grade AS stu_avg_grade
FROM
(
SELECT instructor_id, student_id, AVG(grade) AS avg_grade,
RANK() OVER (PARTITION BY instructor_id ORDER BY AVG(grade) DESC) AS rk
FROM grade
GROUP BY instructor_id, student_id
) t
INNER JOIN instructor i
ON t.instructor_id = i.instructor_id
INNER JOIN student s
ON s.student_id = t.student_id
WHERE t.rk = 1
ORDER BY t.avg_grade DESC;
I'm new to Oracle and try to practice with HR schema. For example I want to report of those whose job is different from the previous job.
Employee name in employees table and job history in job_history table.
I think the following query will help. (I am considering that current JOB_ID is present in the EMPLOYEES table and you want to compare it with the latest previous JOB_ID from JOB_HISTORY table for the employee)
SELECT E.*, JH.LATEST_PREV_JOB_ID
FROM EMPLOYEES E
JOIN (SELECT FIRST_VALUE(JH.JOB_ID) OVER (PARTITION BY JH.EMPLOYEE_ID
ORDER BY JH.START_DATE DESC NULLS LAST) AS LATEST_PREV_JOB_ID,
JH.EMPLOYEE_ID
FROM JOB_HISTORY JH) JH
ON E.EMPLOYEE_ID = JH.EMPLOYEE_ID
WHERE E.JOB_ID <> JH.LATEST_PREV_JOB_ID
----- Update
You want the query without partition by clause (i.e. without WINDOWS function), We can use the NOT EXISTS as follows:
SELECT E.*, JH.LATEST_PREV_JOB_ID
FROM EMPLOYEES E
JOIN (SELECT JH.JOB_ID AS LATEST_PREV_JOB_ID,
JH.EMPLOYEE_ID
FROM JOB_HISTORY JH
WHERE NOT EXISTS (SELECT 1 FROM JOB_HISTORY JHIN
WHERE JHIN.EMPLOYEE_ID = JH.EMPLOYEE_ID
AND JHIN.START_DATE > JH.START_DATE)) JH
ON E.EMPLOYEE_ID = JH.EMPLOYEE_ID
WHERE E.JOB_ID <> JH.LATEST_PREV_JOB_ID
If I understood right your question, then the answer maybe something like this:
select
e.first_name,
e.last_name,
e.job_id as prev_job,
jh.job_id as last_lob
from
employees e,
job_history jh,
(select
employee_id,
max(end_date) as max_end_date
from
job_history
group by
employee_id
) t
where
(jh.employee_id = e.employee_id) and
(jh.job_id <> e.job_id) and
(jh.end_date = t.max_end_date) and
(t.employee_id = jh.employee_id)
I am trying to solve this problem using Oracle SQL but I keep getting this error -
ORA-00923: FROM keyword not found where expected
link to problem - https://leetcode.com/problems/department-top-three-salaries/submissions/
my solution until now - just to query the data -
with temp as
(
select d.Name as Department,
e.Name as Employee,
e.Salary as Salary
from employee e
join department d
on e.DepartmentId = d.Id
)
select *
, rank() over (partition by department order by salary desc) as rr
from temp
but if i simply run this then it works fine -
with temp as
(
select d.Name as Department,
e.Name as Employee,
e.Salary as Salary
from employee e
join department d
on e.DepartmentId = d.Id
)
select *
from temp
And if I run this then it runs okay -
select department, employee, salary
from
(
select A.* , dense_rank() over (partition by department order by salary desc) as rr
from
(
select d.Name as Department,
e.Name as Employee,
e.Salary as Salary
from employee e
join department d
on e.DepartmentId = d.Id
) A
) B
where rr <= 3
does it mean i cannot use the cascading with statements in oracle ?
For instance, cant I write -
with temp as
(
select col1, col2 from table
)
, temp1 as
(
select *, "hello" as col3
from temp
)
select *
from temp1
in Oracle?
If you need to select only all the columns then * without the alias is fine. But if You need to give alias of the table wherever you want to select all the columns of the table using * and also another expression in SELECT clause.
with TEMP AS
( SELECT
COL1,
COL2
FROM table )
, TEMP1 AS
(SELECT
T.*, -- alias here
"hello" AS COL3
FROM TEMP T
)
select * FROM TEMP1;
with temp as
(
select d.Name as Department,
e.Name as Employee,
e.Salary as Salary
from employee e
join department d
on e.DepartmentId = d.Id
)
select T.* -- alias here
, rank() over (partition by department order by salary desc) as rr
from temp T;
How can I convert the below query in Oracle to Hive?
SELECT A.EMP_NO, A.LOGIN_TIMESTAMP FROM TABLE1 A, TABLE2 B
WHERE A.EMP_NO = 1234 AND B.EMP_CURR =
(SELECT MIN(EMP_CURR) FROM TABLE2 WHERE EMP_NO = A.EMP_NO AND
LOGIN_TIMESTAMP = A.LOGIN_TIMESTAMP AND EMP_STATUS_CODE <> 'P')
Use dense_rank() to get rows with minimum EMP_CURR:
SELECT A.EMP_NO, A.LOGIN_TIMESTAMP
FROM TABLE1 A
INNER JOIN (select B.*,
dense_rank() over(partition by B.EMP_NO, B.LOGIN_TIMESTAMP order by B.EMP_CURR) rn
from TABLE2 B where EMP_STATUS_CODE <> 'P'
) B
on B.EMP_NO = A.EMP_NO and B.LOGIN_TIMESTAMP = A.LOGIN_TIMESTAMP and B.rn=1
where B.rn=1 and A.EMP_NO = 1234;
I have 2 CTE.When i try to join them i get an error message "ORA-01789: ".how can i merge the 2 CTE.Is there any other way to get the desired result?
WITH IMPORT_CTE
AS ((select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND A.ERROR_CODE = B.ERROR_CODE ) order by a.pod_id desc)
select t1.*
from IMPORT_CTE t1
where t1.insert_date =(select max(t2.insert_date)
from IMPORT_CTE t2
where t2.POD_ID =t1.POD_ID)
WITH IMPORT_CTE1
AS ((select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND A.ERROR_CODE = B.ERROR_CODE ) order by a.pod_id desc)
select t1.insert_date
from IMPORT_CTE1 t1
where t1.insert_date =(select min(t2.insert_date)
from IMPORT_CTE1 t2
where t2.POD_ID =t1.POD_ID)
You've got an extra set of parentheses in each of your queries. The first one should apparently be:
WITH IMPORT_CTE AS
(select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND
A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND
A.ERROR_CODE = B.ERROR_CODE
order by a.pod_id desc)
select t1.*
from IMPORT_CTE t1
where t1.insert_date = (select max(t2.insert_date)
from IMPORT_CTE t2
where t2.POD_ID = t1.POD_ID)
The second one has a similar problem.
Best of luck.