sql query question - oracle

hey guys, just having a bit of difficulty with a query, i'm trying to figure out how to show the most popular naturopath that has been visited in a centre. My tables look as follows;
Patient(patientId, name, gender, DoB, address, state,postcode, homePhone, businessPhone, maritalStatus, occupation, duration,unit, race, registrationDate , GPNo, NaturopathNo)
and
Naturopath (NaturopathNo, name, contactNo, officeStartTime, officeEndTime, emailAddress)
now to query this i've come up with
SELECT count(*), naturopathno FROM dbf10.patient WHERE naturopathno != 'NULL' GROUP BY naturopathno;
which results in;
COUNT(*) NATUROPATH
2 NP5
1 NP6
3 NP2
1 NP1
2 NP3
1 NP7
2 NP8
My question is, how would I go about selecting the highest count from this list, and printing that value with the naturopaths name? Any suggestions are very welcome,

In MySQL, you could select the top row like:
select *
from Naturopath n
join (
SELECT count(*) as cnt, naturopathno
FROM dbf10.patient
WHERE naturopathno != 'NULL'
GROUP BY naturopathno;
) pat ON pat.naturopathno = n.naturopathno
ORDER BY pat.cnt DESC
LIMIT 1
By the way, if you're checking for null instead of the string "NULL", try:
where naturopathno is not null

You can use the RANK analytic function - this will assign rank "1" to the topmost naturopath, or naturopaths if there is a tie for first place:
SELECT (select name from Naturopath n
where n.NaturopathNo = q.naturopathno)
as TopNaturopathName,
,q.patients
FROM (
SELECT naturopathno, patients,
RANK() OVER (ORDER BY patients DESC) rnk
FROM (
SELECT COUNT(*) AS patients, naturopathno
FROM dbf10.patient
WHERE naturopathno is not null
GROUP BY naturopathno
)
) q
WHERE rnk = 1;

okay figured it out, thanks guys, ive got this which does the job, probably not very efficiently but does do it :)
SELECT *
FROM (
SELECT COUNT(*) AS patients, naturopathno
FROM dbf10.patient
WHERE naturopathno is not null
GROUP BY naturopathno
ORDER BY patients DESC)
WHERE ROWNUM = 1;
any better ways to do this?

Related

In case second highest value is missing then use the highest value of salary from employee table

I have an employee table as below. As you can see that second highest salary is 200
Incase the second highest salary is missing then there will be only one row as shown at last . In this case the query should fetch only 100
I have written query as but it is not working. Please help! Thanks
select salary "SecondHighestSalary" from(
(select id,salary,rank() over(order by salary desc) rnk
from employee2)
)a
where (rnk) in coalesce(2,1)
I have also tried the following but it is fetching 2 rows but i need only 1
It sounds like you'd want something like
with ranked_emp as (
select e.*,
rank() over (order by e.sal desc) rnk,
count(*) over () cnt
from employee2 e
)
select salary "SecondHighestSalary"
from ranked_emp
where (rnk = 2 and cnt > 1)
or (rnk = 1 and cnt = 1)
Note that I'm still using rank since you're using that in your approach and you don't specify how you want to handle ties. If there are two employees with the same top salary, rank will assign both a rnk of 1 and no employee would have a rnk of 2 so the query wouldn't return any data. dense_rank would ensure that there was at least one employee with a rnk of 2 if there were employees with at least 2 different salaries. If there are two employees with the same top salary, row_number would arbitrarily assign one the rnk of 2. The query I posted isn't trying to handle those duplicate situations because you haven't outlined exactly how you'd want it to behave in each instance.
If you are in Oracle 12.2 or higher, you can try:
select distinct id,
nvl
(
nth_value(salary, 2) from first
over(partition by id
order by salary desc
range between unbounded preceding and unbounded
following),
salary
) second_max_salary
from employee2

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!!

HiveSQLException: cannot recognize input near 'SELECT' 'MAX' '(' in expression specification

I'm trying to get the maximum value of a count. The code is as follows
SELECT coachID, COUNT(coachID)
FROM coaches_awards GROUP BY coachID
HAVING COUNT(coachID) =
(
SELECT MAX(t2.awards)
FROM (
SELECT coachID, count(coachID) as awards
FROM coaches_awards
GROUP BY coachID
) t2
);
Yet something keeps failing. The inner query works and gives the answer that I want and the outer query will work if the inner query is replaced by the number required. So I'm assuming I've made some syntax error.
Where am I going wrong?
If you are just looking for one row, why not do:
SELECT coachID, COUNT(coachID) as cnt
FROM coaches_awards
GROUP BY coachID
ORDER BY cnt DESC
LIMIT 1;
If you want ties, then use RANK() or DENSE_RANK():
SELECT ca.*
FROM (SELECT coachID, COUNT(*) as cnt,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM coaches_awards
GROUP BY coachID
) ca
WHERE seqnum = 1;

Please help me to optimize the below mentioned script as the same table(i.e. Incident_Audit_log) has utilized multiple times?

select A.*
from Incident_Audit_log a where incident_audit_log_id in
(select top 1 incident_audit_log_id from Incident_Audit_log b
where b.incident_id=a.incident_id and b.status_did=a.status_did
and b.tracking_code_did = (select tracking_code_did
from Incident_Audit_log where update_date = (select MAX(update_date)
from Incident_Audit_log where Status_did in (103, 1035)
and incident_id = b.incident_id)
and incident_id = b.incident_id)
order by update_date asc)
I am not sure what you want to achieve but I guess that you want to extract row with new newest update and status_did equal to 13 and 1035.
In that case this should work:
select *
from (
select ROW_NUMBER() OVER(ORDER BY update_date DESC) AS rn,
*
from Incident_Audit_log
where status_did in (103, 1035)
) as SubQueryAlias
where rn = 1
In case not , provide more info.

No Results returned for ROW_NUMBER() query

I am getting "no results returned" for the following query:
SELECT
Referer
FROM
(SELECT
ROW_NUMBER() OVER (ORDER BY CT.Referer ASC) AS RowNum,
CT.Referer, CT.LastModified
FROM
ClickTrack CT
JOIN
OrderTrack OT ON OT.ClickTrackID = CT.ClickTrackID
GROUP BY
CT.Referer, CT.LastModified
HAVING
LEN(CT.Referer) > 0) as num
WHERE
RowNum = 1
AND LastModified BETWEEN '07/06/2013' and '08/05/2013'
Curiously, when I leave off RowNum = 1, I get the full list of values. I need to get one at a time though to assign to a variable and drop into a temporary table.
The end query will be in a while loop using scalar variables in place of the date ranges and RowNum comparison.
Any help is appreciated. Thank you!
I'm thinking RowNum 1 may not have a date between your selections. Maybe put the date selection inside so that you know that the first one matches.
SELECT Referer
FROM (SELECT ROW_NUMBER() OVER (ORDER BY CT.Referer ASC)
AS RowNum, CT.Referer, CT.LastModified
FROM ClickTrack CT
JOIN OrderTrack OT ON OT.ClickTrackID = CT.ClickTrackID
WHERE CT.LastModified BETWEEN '07/06/2013' and '08/05/2013'
GROUP BY CT.Referer, CT.LastModified
HAVING LEN(CT.Referer) > 0) as num
WHERE RowNum = 1

Resources