Right outer join on two tables where ON clause has a subquery - oracle

I am trying to perform a right outer join on two liferay tables — users_ and expandovalue — to get a result set.
When I did the following query on all the users, I got desired result.
SELECT USER_.FIRSTNAME
, USER_.LASTNAME
, USER_.EMAILADDRESS
, USER_.JOBTITLE
, expandovalue.data_
from expandovalue
right outer join
user_ on expandovalue.classpk = user_.userid
and expandovalue.columnid =35695;
When tried to do the same for a set of users (part of a user group) it errored out. Query below:
SELECT USER_.FIRSTNAME
, USER_.LASTNAME
, USER_.EMAILADDRESS
, USER_.JOBTITLE
, expandovalue.data_
from expandovalue
right outer join
user_ on expandovalue.classpk
in (select userid
from user_
where userid
in ( select userid
from users_usergroups
where usergroupid = 40073
) and status =0) = user_.userid in
(select userid
from user_
where userid
in ( select userid
from users_usergroups
where usergroupid = 40073
)
and status =0
) and expandovalue.columnid =35695
Here's the subquery which gives the userids of people in a particular usergroup.
(select userid
from user_
where userid in
( select userid
from users_usergroups
where usergroupid = 40073)
and status =0
)
Am I going in a completely incorrect direction? Please advise.

Try this query:
SELECT USER_.FIRSTNAME,
USER_.LASTNAME,
USER_.EMAILADDRESS,
USER_.JOBTITLE,
expandovalue.data_
from expandovalue
right outer join user_
on expandovalue.classpk IN
(select userid
from user_
where userid in (select userid
from users_usergroups
where usergroupid = 40073) and
status = 0) AND
user_.userid in (select userid
from user_
where userid in (select userid
from users_usergroups
where usergroupid = 40073) AND
status =0) AND
expandovalue.columnid = 35695
There was an "AND" missing after the end of the first subquery.

Related

How to union two tables in the lef join of third table laravel?

I have these two queries:
SELECT salesconsultant AS emp_names,
lotid AS lot_id,
communityid AS lot_community,
lotnumber AS lot_no,
phasenumber AS lot_phase,
clientid AS lot_buyer,
lotstatusid AS lot_status,
lotaddress AS address,
pkg AS pack_id,
pkg_abbr AS pack_abbre,
deposit AS depst,
currentprice AS contract_price,
salesconsultant AS agent_name FROM `iv_reports_all_wms`
WHERE is_active_report = 0
AND lotid <> ''
AND rescined = 0 AND region IN ("SL")
ORDER BY `dig` ASC,
`agreedate` ASC
AND
(SELECT
id,
NAME,
lastname AS l_name
FROM
`iv_employee`
WHERE id = 6588)
UNION
(SELECT
userId AS id,
firstname AS NAME,
lastname AS l_name
FROM
`ivhusersdeleted`
WHERE userId = 6588)
I want to avoid to run the second query in foreach after the first query.
i want to use the second one in the left join of first in laravel. Can anyone help

Assign a Name to the Sub queries in Oracle

I have 2 sub queries which are repeated and are very long so I want to give it a name and then refer that name in the query as mentioned in https://stackoverflow.com/a/3058938/6700081.
I have a Customers table with ID, Name, OrderID
I have the Orders table with ID (this is the order ID so it is also the Foreign key), Price, Order_Date
This is my original query which is working fine:
SELECT CUSTOMERS.name, ORDERS.price FROM
CUSTOMERS INNER JOIN ORDERS
ON (CUSTOMERS.ORDER_ID = ORDERS.ID)
WHERE ORDERS.PRICE = (SELECT MAX(ORDERS.PRICE) from ORDERS where ORDERS.ORDER_DATE <= (SELECT ADD_MONTHS((SELECT MIN(ORDER_DATE) FROM ORDERS), 12*10) from ORDERS WHERE ROWNUM = 1))
AND ORDERS.ORDER_DATE <= (SELECT ADD_MONTHS((SELECT MIN(ORDER_DATE) FROM ORDERS), 12*10) from ORDERS WHERE ROWNUM = 1);
I tried to change it to a named query as below:
WITH MAX_ORDER_DATE as (SELECT ADD_MONTHS((SELECT MIN(ORDER_DATE) FROM ORDERS), 12*10) from ORDERS WHERE ROWNUM = 1),
WITH MAX_ORDER_PRICE as (SELECT MAX(ORDERS.PRICE) from ORDERS where ORDERS.ORDER_DATE <= (MAX_ORDER_DATE))
SELECT CUSTOMERS.name, ORDERS.price FROM
CUSTOMERS INNER JOIN ORDERS
ON (CUSTOMERS.ORDER_ID = ORDERS.ID)
WHERE ORDERS.PRICE = (MAX_ORDER_PRICE)
AND ORDERS.ORDER_DATE <= (MAX_ORDER_DATE);
But I get an error related to invalid table name. What is wrong with this query?
Your corrected query:
WITH MAX_ORDER_DATE AS (
SELECT ADD_MONTHS((SELECT MIN(ORDER_DATE) FROM ORDERS), 12*10) AS max_date
FROM ORDERS
WHERE ROWNUM = 1
),
MAX_ORDER_PRICE AS (
SELECT MAX(ORDERS.PRICE) AS max_price
FROM ORDERS
WHERE ORDERS.ORDER_DATE <= (SELECT max_date FROM MAX_ORDER_DATE)
)
SELECT c.name, o.price
FROM CUSTOMERS c
INNER JOIN ORDERS o
ON c.ORDER_ID = o.ID
WHERE
o.PRICE = (SELECT max_price FROM MAX_ORDER_PRICE) AND
o.ORDER_DATE <= (SELECT max_date FROM MAX_ORDER_DATE);
The main issues I noticed with your syntax were that you repeated WITH for each common table expression, when you only need to state it once at the beginning of the definitions. Also, if you want to use the single values you define in the two CTEs, you should use a subquery against those CTEs. Finally, I added aliases to the columns you select in the CTEs.

Oracle Left join give duplicate

I am trying to get all the customers whether they have install service or not from TRANS_TABLE.
NOA- query to get only the MAX product and join again with TRANS_TABLE by email id to get the all the MAX customers details (wwhther they have install service by adding Y OR N, but this query return duplicate with REP Product as well
Below is my Oracel Query which give duplicated
with CTE as (SELECT NOA.*,
CASE
WHEN TRANS_TABLE.product_name LIKE '%Installation%' THEN 'Y'
ELSE 'N'
END AS Installaion ,
ROW_NUMBER() OVER (PARTITION BY TRANS_TABLE.email_address ORDER BY TRANS_TABLE.email_address) AS rn
FROM (SELECT DISTINCT email_address
FROM TRANS_TABLE
WHERE email_address IS NOT NULL
and pdct_name like '%MAX%'
) NOA
LEFT JOIN TRANS_TABLE
ON NOA.email_address = TRANS_TABLE.email_address
select * from cte where rn='1'
The following code will help:
CTE AS (
SELECT
NOA.*,
CASE
WHEN TRANS_TABLE.PDCT_NAME LIKE '%INSTALLATION%' THEN 'Y' -- case sensitive name is used
ELSE 'N'
END AS INSTALLAION,
ROW_NUMBER() OVER(
PARTITION BY TRANS_TABLE.EMAIL_ADDRESS
ORDER BY
TRANS_TABLE.EMAIL_ADDRESS
) AS RN
FROM
(
SELECT DISTINCT
PDCT_NAME,
EMAIL_ADDRESS
FROM
TRANS_TABLE
WHERE
EMAIL_ADDRESS IS NOT NULL
AND PDCT_NAME LIKE '%MAX%'
) NOA
LEFT JOIN TRANS_TABLE ON NOA.EMAIL_ADDRESS = TRANS_TABLE.EMAIL_ADDRESS
WHERE TRANS_TABLE.PDCT_NAME NOT LIKE '%REP%') -- added this WHERE condition
SELECT
PDCT_NAME, EMAIL_ADDRESS, INSTALLAION
FROM
CTE
WHERE
RN = '1'
db<>fiddle demo
Cheers!!

Oracle select distinct with join and multiple columns

Unfortunately this database has a ton of duplicate email addresses in it. I need to do a query and return only unique emails, doesn't really matter which one.
The query I have looks like this, can't really figure out what to add to not get duplicate emails returned. Can anyone think of anything?
select c.cid, c.email, c.uuid, e.code
from c
inner join e on e.cid = c.cid
where regexp_like(c.email, '\.net$', 'i');
-- Adding some additional info on request
The above query returns the following results, where you can see there are duplicates. I'm interested in only returning one row per unique email address.
3478|cust1#cust1.net|ouskns;dhf|1
3488|cust2#cust2.net|jlsudo;uff|0
3598|cust3#cust3.net|dl;udjffff|1
3798|cust1#cust1.net|osuosdujff|1
3888|cust1#cust1.net|odsos7jfff|1
-- Solution, thanks Mathguy
select cid, email, uuid, code
from
(select c.cid, c.email, c.uuid, e.code, row_number() over (partition by
c.email order by null) as rn
from c
inner join e on e.cid = c.cid
where regexp_like(c.email, '\.net$', 'i')
)
where rn = 1;
If it works as is and the only problem is the duplicates, you can change c.email to MAX(c.email) as email in the select clause, and add a group by clause to group by the other columns included in select.
EDIT: (actually I should delete the original answer since the OP clarified his question was quite different from what he seemed to ask originally - but that would also delete the comments... so editing instead)
If your query produces the desired results, but now you must pick just one random row per email address, you can try this:
select cid, email, uuid, code
from
( -- .... copy your select query here
-- ADD one column to the select line like so:
-- select c.cid, c.uuid, c.email, e.code,
-- row_number() over (partition by c.email order by null) as rn
-- ....
)
where rn = 1;
Using DISTINCT :
select DISTINCT c.email
from c
inner join e on e.cid = c.cid
where regexp_like(c.email, '\.net$', 'i');
Or using GROUP BY (and you get the number of dups in the cnt column)
select c.email, count(*) as cnt
from c
inner join e on e.cid = c.cid
where regexp_like(c.email, '\.net$', 'i')
GROUP BY c.email;

Missing right parenthesis error in query oracle

Tables needed -
Habits(conditionId, name)
Patient(patientId, name, gender, DoB, address, state,postcode, homePhone, businessPhone, maritalStatus, occupation, duration,unit, race, registrationDate , GPNo, NaturopathNo)
PatientMetabolic (functionNo, patientId, score)
The Question Is -
Question - Display the details of the patient (i.e. Name, Gender, Address, Postcode, DOB) who smokes and has the highest (most severe) total of metabolic functions.
(conditionid for smoke is H1 in Habit table)
(metabolic function are in patientbetabolic table functionNo)
(To find the highest most severe total of metabolic function we need to create a sum of score which tells who has the most metabolic functions)
My query -
SELECT *
FROM patient
where patientid IN (SELECT patientid,SUM(score) as totalscore
from PATIENTMETABOLIC
where patientid IN (SELECT patientid
from patienthabit
where conditionid = 'H1')
group by patientid
order by totalscore desc);
Error:
ORA-00907: missing right parenthesis
An alternative way to do this is by using joins.
select * from (select p.patientid,p.name,sum(pm.score) as total from patient p join patienthabit ph on p.patientid = ph.patientid
and ph.conditionid = 'H1' Left join patientmetabolic pm
on p.patientid = pm.patientid group by p.patientid,p.name order by 3 desc) where ROWNUM = 1;
Try this:
SELECT *
FROM PATIENT
WHERE PATIENTID = (SELECT PATIENTID
FROM (SELECT patientid, SUM(score)
from PATIENTMETABOLIC
where patientid IN (SELECT patientid
from patienthabit
where conditionid = 'H1')
group by patientid
order by SUM(score) desc)
WHERE ROWNUM = 1);
SQLFiddle here
Share and enjoy.
Since the first inner query returns patientid and totalscore, you can't use it as a list against IN operator.
The result of this query might be similar to that of your query:
SELECT p.*
FROM patient p JOIN
patienthabit ph ON p.patientid=ph.patientid
WHERE ph.conditionid='H1'

Resources