Missing right parenthesis error in query oracle - 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'

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.

Select client informations about his reservation in SQL*Plus

I'd like to isplay the name, address and phone number for the clients who has not made any reservations for the past two months.
The tables are :
CLIENT (
ClientNo,
Name,
Sex,
DOB,
Address,
Phone,
Email,
Occupation,
MaritalStatus,
Spouse,
Anniversary
)
RESERVATION
ResNo,
ResDate,
NoOfGuests,
StartDate,
EndDate,
ClientNo,
Status
)
I tried:
SELECT Name, Address, Phone, ResNo
FROM Client C, Reservation R
WHERE Date_Column >= ResDate R(MONTH, -3, GETDATE())
ORDER BY Name DESC
You need an outer join, with all conditions in the join, and then filter out all successful joins:
SELECT C.*
FROM Client C
LEFT JOIN Reservation R ON C.ID = R.ID -- outer join
AND R.ResDate >= add_months(TRUNC(SYSDATE) + 1, 2) -- condition in join
WHERE R.ID IS NULL -- only return missed joins
ORDER BY Name ASC
You want the missed joins - ones where there are no reservations at all given the conditions. Such missed joins have all-nulls in the joined table's columns, so filtering on (one of) those columns being null will return clients who don't have any such reservations.
Try to make your where condition like
ResDate >= add_months(TRUNC(SYSDATE) + 1, 2)
Also you are missing the JOIN for your table. So you need to put the JOIN like
SELECT C.Name, C.Address, C.Phone, R.ResNo, R.ResDate
FROM Client C INNER JOIN Reservation R ON C.ID = R.ID --Change the column for Joing as per your table structure
WHERE R.ResDate >= add_months(TRUNC(SYSDATE) + 1, 2))
ORDER BY Name ASC;

Oracle Missing right parenthesis ORA-00907

Consider a database schema with three relations:
Employee (*eid:integer*, ename:string, age:integer, salary:real)
Works (*eid:integer*, *did:integer*, pct_time:integer)
Department(*did:integer*, dname:string, budget:real, managerid:integer)
Query the view above to find the name of the manager who manages most employees. If thesame employee works in several departments, that employee is counted once in each of the
departments. The manager is included in the count the same as all other employees, i.e., based
on his or her records in the Works table.
Why do I get this error:
ORDER BY SUM (EmpCount) DESC)
*
ERROR at line 6:
ORA-00907: missing right parenthesis
Here is my query:
SELECT distinct(MgrName)
FROM ManagerSummary
WHERE MgrID = (SELECT MgrID
FROM ManagerSummary
GROUP BY MgrID
ORDER BY SUM (EmpCount) DESC
LIMIT 1 );
The view is:
CREATE VIEW ManagerSummary (DeptName, MgrID, MgrName, MgrSalary, EmpCount)
AS SELECT d.dname, d.managerid, e.ename, e.salary,
(SELECT COUNT (w.did)
FROM works w
WHERE w.did = d.did
GROUP BY w.did)
FROM employee e, department d WHERE d.managerid = e.eid;
Thank you
Update: Changing LIMIT 1 for WHERE ROWNUM = 1 doesn't help
Try this
SELECT DISTINCT (MgrName)
FROM ManagerSummary
WHERE MgrID = (SELECT MgrId
FROM ( SELECT MgrId, SUM (empcount) AS maxemp
FROM ManagerSummary
GROUP BY MgrId
ORDER BY SUM (empcount) DESC)
WHERE ROWNUM = 1)
You seem to want the name of the manager that has the most employees.
My guess is that you can do this in Oracle as:
select ms.MgrName
from (select ms.*
from ManagerSummary ms
order by EmpCount desc
) ms
where rownum = 1;
It is hard for me to envision a table called ManagerSummary that would have more than one row per MgrId. That's why I don't think aggregation is necessary.
SELECT mgrname
FROM (SELECT mgrname, numemps
FROM (SELECT mgrname, count(*) numemps
FROM mgrsummary
GROUP BY mgrname)
ORDER BY NUMEMPS desc);
Just noticed - this is based on a view. This is ~not~ going to perform well.

Group by and bring back value in first row

I have query
SELECT ID, TIME, PRICE, QTY
FROM myTable
that returns:
ID TIME PRICE QTY
1295179228 1/29/2015 20:59:37 15.24 1112
1295179228 1/29/2015 20:59:37 15.23 2
1295179228 1/29/2015 20:59:38 15.28 22
1295179228 1/29/2015 20:59:38 15.27 1800
I am then using group by to return the min time, average price and sum of qty BUT I also want to return the first time
SELECT ID, t2.name, min(TIME) as MinTIME, avg(PRICE) as AVGPrice, sum( QTY) as SUMQTY
FROM myTable t inner join table2 t2 on t.id = t2.id
group by ID, t2.name
But how do I add a column in that group by query above that will also return the first PRICE. In that case that would be 15.24
I have been googling and I see oracle has FIRST() and FIRST_VALUE() functions but I could not get them to work.
Thank you.
Assuming that "first price" means "price with the earliest time"
min(price) keep (dense_rank first order by time)
WITH CTE AS
(SELECT ID,"TIME",PRICE,QTY,ROW_NUMBER() OVER (PARTITION BY id ORDER BY TIME ASC) as rn
FROM t)
SELECT ID, min("TIME") as MinTIME, avg(PRICE) as AVGPrice, sum( QTY) as SUMQTY,
MAX(CASE WHEN rn=1 THEN PRICE ELSE 0 END) as FirstPrice
FROM CTE
group by ID

Resources