Oracle how to do outer join in line select - oracle

I have three selects
SELECT
mam.fecha fecha
, u.COD_USUARIO usuario
, u.NOMBREAPELLIDOS nombre
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha ASC) AS rn_asc
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha DESC) AS rn_desc
,mam.accion accion
,u.ID_CENTRO_GESTION centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'A'
and trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy')
and mam.cod_usuario = '9717703'
and u.id_centro_gestion = '3'
order by u.cod_usuario
Second one, it is the same changing the where
SELECT
mam.fecha fecha
, u.COD_USUARIO usuario
, u.NOMBREAPELLIDOS nombre
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha ASC) AS rn_asc
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha DESC) AS rn_desc
,mam.accion accion
,u.ID_CENTRO_GESTION centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'D'
and trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy')
and mam.cod_usuario = '9717703'
and u.id_centro_gestion = '3'
order by u.cod_usuario
Thrid one
SELECT COUNT (*) numeroincidencias, ri.cod_usuario usuario
FROM r_incidencias ri
WHERE TRUNC (ri.fecha_inc) = TO_DATE ('13/09/2018', 'dd/mm/yyyy')
and ri.cod_usuario = '9717703'
GROUP BY ri.cod_usuario
I want to link these select by cod_usuario. It couldn't be rows in the first, second or third select.
How can I do an outer join of these selects?

Make each of your selects a common table expression, then full outer join them together:
WITH cte1 AS (SELECT mam.fecha AS fecha,
u.COD_USUARIO AS usuario,
u.NOMBREAPELLIDOS AS nombre,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha DESC) AS rn_desc,
mam.accion AS accion,
u.ID_CENTRO_GESTION AS centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u
ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'A' and
trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy') AND
mam.cod_usuario = '9717703' AND
u.id_centro_gestion = '3'
order by u.cod_usuario),
cte2 AS (SELECT mam.fecha AS fecha,
u.COD_USUARIO AS usuario,
u.NOMBREAPELLIDOS AS nombre,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha DESC) AS rn_desc,
mam.accion AS accion
u.ID_CENTRO_GESTION AS centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u
ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'D' and
trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy') AND
mam.cod_usuario = '9717703' AND
u.id_centro_gestion = '3'
order by u.cod_usuario),
cte3 AS (SELECT COUNT (*) numeroincidencias,
ri.cod_usuario usuario
FROM r_incidencias ri
WHERE TRUNC (ri.fecha_inc) = TO_DATE ('13/09/2018', 'dd/mm/yyyy') AND
ri.cod_usuario = '9717703'
GROUP BY ri.cod_usuario)
SELECT *
FROM cte1
FULL OUTER JOIN cte2
ON cte2.cod_usuario = cte1.cod_usuario
FULL OUTER JOIN cte3
ON cte3.cod_usuario = COALESCE(cte1.cod_usuario, cte2.cod_usuario)

Related

Using JOIN with cte

I have the following setup, which seems to be working fine. I am having trouble modifying the query to include the department_name in the output.
I can't seem to get the JOIN working with the CTE. Its probably something trivial but after many attempts I can't get it to work.
Any help would be appreciated.
Below is my setup and test case.
CREATE TABLE departments( department_id, department_name) AS
SELECT 1, 'IT' FROM DUAL UNION ALL
SELECT 2, 'DBA' FROM DUAL;
CREATE TABLE employees (employee_id, first_name, last_name, hire_date, salary, department_id) AS
SELECT 1, 'Lisa', 'Saladino', DATE '2001-04-03', 100000, 1 FROM DUAL UNION ALL
SELECT 2, 'Abby', 'Abbott', DATE '2001-04-04', 50000, 1 FROM DUAL UNION ALL
SELECT 3, 'Beth', 'Cooper', DATE '2001-04-05', 60000, 1 FROM DUAL UNION ALL
SELECT 4, 'Carol', 'Orr', DATE '2001-04-06', 70000,1 FROM DUAL UNION ALL
SELECT 5, 'Vicky', 'Palazzo', DATE '2001-04-07', 88000,2 FROM DUAL UNION ALL
SELECT 6, 'Cheryl', 'Ford', DATE '2001-04-08', 110000,1 FROM DUAL UNION ALL
SELECT 7, 'Leslee', 'Altman', DATE '2001-04-10', 666666, 1 FROM DUAL UNION ALL
SELECT 8, 'Jill', 'Coralnick', DATE '2001-04-11', 190000, 2 FROM DUAL UNION ALL
SELECT 9, 'Faith', 'Aaron', DATE '2001-04-17', 122000,2 FROM DUAL;
WITH cte AS (
SELECT department_id,
first_name,
last_name,
salary,
DENSE_RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
)
SELECT department_id,
/* department_name */
first_name,
last_name,
salary
FROM cte
WHERE rnk=1
You did not join the table.
WITH cte AS (
SELECT department_id,
first_name,
last_name,
salary,
DENSE_RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
)
SELECT e.department_id,
d.department_name,
e.first_name,
e.last_name,
e.salary
FROM cte e
INNER JOIN departments d
ON (d.department_id = e.department_id)
WHERE rnk=1
or:
WITH cte AS (
SELECT e.department_id,
d.department_name,
e.first_name,
e.last_name,
e.salary,
DENSE_RANK() OVER(PARTITION BY e.department_id ORDER BY e.salary DESC) AS rnk
FROM employees e
INNER JOIN departments d
ON (d.department_id = e.department_id)
)
SELECT department_id,
department_name,
first_name,
last_name,
salary
FROM cte
WHERE rnk=1
or using a sub-query, instead of the sub-query factoring clause:
SELECT e.department_id,
d.department_name,
e.first_name,
e.last_name,
e.salary
FROM (
SELECT department_id,
first_name,
last_name,
salary,
DENSE_RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) e
INNER JOIN departments d
ON (d.department_id = e.department_id)
WHERE rnk=1
or:
SELECT department_id,
department_name,
first_name,
last_name,
salary
FROM (
SELECT e.department_id,
d.department_name,
e.first_name,
e.last_name,
e.salary,
DENSE_RANK() OVER(PARTITION BY e.department_id ORDER BY e.salary DESC) AS rnk
FROM employees e
INNER JOIN departments d
ON (d.department_id = e.department_id)
)
WHERE rnk=1
fiddle

ORA-00907 error at order by in Oracle 11g

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

Converting Oracle Query to Hive

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;

ansi join on oracle 8i

I've got this query in Oracle 8i:
select
decode(seqnum,
1 , '1',
cnt, '0'
) as value1,
decode(seqnum,
1 , t.BEGIN_DT,
cnt, t.END_DT
) as TIME1,
t4.UNIT1 || '.SUBBATCH_TRIGGER' TAG
from (select t.*,
row_number() over(partition by t.BATCH_ID, t.plant_unit, t3.ID2 order by t.BEGIN_DT) as seqnum,
count(*) over(partition by t.BATCH_ID, t.plant_unit, t3.ID2) as cnt
from SCH2.tb_pg_unit_stap t
join (select ID1,batch_id from SCH2.VW_BATCH) t2 on t.BATCH_ID = t2.BATCH_ID
join (select ID2,ID1 from SCH1.STEP) t3 on t3.ID1 = t2.ID1) t
join SCH2.TB_W_MACHINE t4 on t4.plant_unit = t.plant_unit
where (seqnum = 1
or seqnum = cnt) AND (t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');
I've recently asked the Stackoverflow community and they told me Oracle 8i doesn't support ansi joins.
how can I rewrite this query for Oracle 8i?
Thanks in advance!
select decode(seqnum, 1 , '1',
cnt, '0') as value1,
decode(seqnum, 1, t.BEGIN_DT,
cnt, t.END_DT) as TIME1,
t4.UNIT1 || '.SUBBATCH_TRIGGER' TAG
from (select t.*,
row_number() over(partition by t.BATCH_ID, t.plant_unit, t3.ID2 order by t.BEGIN_DT) as seqnum,
count(*) over(partition by t.BATCH_ID, t.plant_unit, t3.ID2) as cnt
from SCH2.tb_pg_unit_stap t,
(select ID1,batch_id from SCH2.VW_BATCH) t2,
(select ID2,ID1 from SCH1.STEP) t3
where t.BATCH_ID = t2.BATCH_ID
and t3.ID1 = t2.ID1) t,
SCH2.TB_W_MACHINE t4
where t4.plant_unit = t.plant_unit
and (seqnum = 1 or seqnum = cnt)
AND (t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');

Query works on Oracle 11g but fails on Oracle 8i

I am running this query in Oracle 11g with no problem:
select (case
when seqnum = 1 then
'1'
when seqnum = cnt then
'0'
end) as value1,
(case
when seqnum = 1 then
t.BEGIN_DT
when seqnum = cnt then
t.END_DT
end) as TIME1,
t4.UNIT1 || '.SUBBATCH_TRIGGER' TAG
from (select t.*,
row_number() over(partition by t.BATCH_ID, t.plant_unit, t3.ID2 order by t.BEGIN_DT) as seqnum,
count(*) over(partition by t.BATCH_ID, t.plant_unit, t3.ID2) as cnt
from SCH2.tb_pg_unit_stap t
join (select ID1,batch_id from SCH2.VW_BATCH) t2 on t.BATCH_ID = t2.BATCH_ID
join (select ID2,ID1 from SCH1.STEP) t3 on t3.ID1 = t2.ID1) t
join SCH2.TB_W_MACHINE t4 on t4.plant_unit = t.plant_unit
where (seqnum = 1
or seqnum = cnt) AND (t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');
But when I run it in Oracle 8i (8.7.1) it gives ORA-00933: SQL command not properly ended.
Is there anys special consideration I must know for running sql commands in Oracle 8i?
Thanks in advance
AFAK case command was introduced since 9i.
OK - trip--down-memory-lane time:
select decode(seqnum,
1, '1',
cnt, '0') as value1,
decode(seqnum,
1, t.BEGIN_DT,
cnt, t.END_DT) as TIME1,
t4.UNIT1 || '.SUBBATCH_TRIGGER' TAG
from (select t.*,
row_number() over (partition by t.BATCH_ID, t.plant_unit, t3.ID2
order by t.BEGIN_DT) as seqnum,
count(*) over (partition by t.BATCH_ID, t.plant_unit, t3.ID2) as cnt
from SCH2.tb_pg_unit_stap t
INNER join (select ID1, batch_id
from SCH2.VW_BATCH) t2
on t.BATCH_ID = t2.BATCH_ID
INNER join (select ID2, ID1
from SCH1.STEP) t3
on t3.ID1 = t2.ID1) t
INNER join SCH2.TB_W_MACHINE t4
on t4.plant_unit = t.plant_unit
where (seqnum = 1 or seqnum = cnt) AND
(t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');

Resources