SQL query multiple admission_date same patient id - sql

I am trying to query patients admitted multiple times for same diagnosis.
Show patient_id, diagnosis from admissions. Find patients admitted multiple times for the same diagnosis.
SELECT
patient_id,
diagnosis,admission_date
FROM
admissions
GROUP BY
diagnosis,
admission_date
HAVING
COUNT(admission_date) > 1;
I thought maybe subquery would be better solution. But have no idea, how to query same diagnosed patient_id s

Without subquery:
SELECT a1.patient_id, a1.diagnosis
FROM admissions a1
JOIN admissions a2
ON a1.patient_id = a2.patient_id AND a1.diagnosis = a2.diagnosis
GROUP BY a1.patient_id, a1.diagnosis
HAVING COUNT(*) > 1
With subquery:
SELECT patient_id, diagnosis
FROM admissions
WHERE patient_id IN (
SELECT patient_id
FROM admissions
GROUP BY patient_id, diagnosis
HAVING COUNT(*) > 1
)
Hope it helps.

Related

Summing duplicate purchases

I am trying to write a query that selects from a list of employee_id and find duplicate book purchases (book_id) and associated cost savings (list_price). If a duplicate exists, it needs sum the prices of the amount of duplicate book_id's.
So if someone has a book costing $10 associated to their employee_id and the book is offered to them again, they don't have to buy it and there is a savings of $10. If that happens again, there's a savings of $20.
I tried a having>1 but I can't seem to get the query correct to accurately sum the savings.
Any help is appreciated.
To start,
select employee_id, book_id, count(*)
from book_purchases
group by employee_id, book_id
having count(*) > 1
gets you the list you need.
If we don't have to worry about the price changing, then we just add a column or two more to get:
select employee_id, book_id,
count(*) as copies_purchased,
sum(list_price) as total_spent,
count(*) - 1 as copies_unnecessarily_purchased,
(count(*) - 1) * avg(list_price) as amount_overspent
from book_purchases
group by employee_id, book_id
having count(*) > 1
Of course you can join to the employee and book tables to get names and titles to fat out the results a bit.
To get the total amount overspent by each employee, you could wrap the above query thusly:
select a.employee_id, sum(a.amount_overspent) as total_amount_overspent
from (
select employee_id, book_id,
count(*) as copies_purchased,
sum(list_price) as total_spent,
count(*) - 1 as copies_unnecessarily_purchased,
(count(*) - 1) * avg(list_price) as amount_overspent
from book_purchases
group by employee_id, book_id
having count(*) > 1
) as a
group by a.employee_id
Lastly, I went ahead and joined to an employee table that I presumed you have while I was at it:
select a.employee_id, emp.employee_name, sum(a.amount_overspent) as total_amount_overspent
from (
select employee_id, book_id,
count(*) as copies_purchased,
sum(list_price) as total_spent,
count(*) - 1 as copies_unnecessarily_purchased,
(count(*) - 1) * avg(list_price) as amount_overspent
from book_purchases
group by employee_id, book_id
having count(*) > 1
) as a
inner join employee as emp on emp.employee_id = a.employee_id
group by a.employee_id, emp.employee_name
To be clear, these aren't four separate queries; they're just intermediate stages in building the single query you see at the end.
I hope this helps.

SQL which patients had appointments with more than 1 doctor (postgresql)

I have a table appointments(id,patientID,doctorID)
I want to check which patients had appointments with more than 1 doctor
You can use aggregation and the HAVING clause to check if a patient has more than one distinct doctor.
select patientId
from appointments
group by patientId
having count(distinct doctorId) > 1;

How to find duplicate record for same date

I have a room inventory table each room has one record for each day,
but some rooms have double record for a day. I want to query to pull out those id.
Inventory_table => id, roomid, inv_date....
The following may get you a list of the rooms with duplicates.
select id, roomid, inv_date, count(room)
from room_inventory
group by id, roomid, inv_date
having count(room) > 1;
Select Id, count(*) from inventory_table group by roomid, inv_date having count(*)>1
select empno,count() from emp group by empno having count()>1;
its with reapted values
select * from emp where rowid not iN(select min(rowid) from emp group by deptno)

Find multiple maximum values form a table

I have read answers to similar questions but I cannot find a solution to my particular problem.
I will use a simple example to demonstrate my question.
I have a table called 'Prizes' with two columns: Employees and Awards
The employee column lists the employee's ID and award shows a single award won by the employee. If an employee has won multiple awards their ID will be listed in multiple rows of the table along with each unique award.
The table would look as follows:
Employee AWARD
1 Best dressed
1 Most attractive
2 Biggest time waster
1 Most talkative
3 Hardest worker
4 Most shady
3 Most positive
3 Heaviest drinker
2 Most facebook friends
Using this table, how would I select the ID's of the employees who won the most awards?
The output should be:
Employee
1
3
For the example as both these employees won 3 awards
Currently, the query below outputs the employee ID along with the number of awards they have won in descending order:
SELECT employee,COUNT(*) AS num_awards
FROM prizes
GROUP BY employee
ORDER BY num_awards DESC;
Would output:
employee num_awards
1 3
3 3
2 2
4 1
How could I change my query to select the employee(s) with the most awards?
A simple way to express this is using rank() or dense_rank():
SELECT p.*
FROM (SELECT employee, COUNT(*) AS num_awards,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM prizes
GROUP BY employee
) p
WHERE seqnum = 1;
Being able to combine aggregation functions and analytic functions can make these queries much more concise.
You can use dense_rank to get all the rows with highest counts.
with cnts as (
SELECT employee, count(*) cnt
FROM prizes
GROUP BY employee)
, ranks as (select employee, cnt, dense_rank() over(order by cnt desc) rnk
from cnts)
select employee, cnt
from ranks where rnk = 1

SQL query error: “right parenthesis missing missing” [duplicate]

This question already has answers here:
Sql query error: "From keyword missing" [closed]
(3 answers)
Closed 9 years ago.
The problem: Display hospitalid, hname, htype of hospital(s) which has the highest number of doctors associated with them.
The patient table:
patientid
pname
address
amount
ptype
The hospital table
hospitalid
hname
htype
The doctor table:
doctorid
dname
specialization
hospitalid
status
The billing table:
billingid
patientid
doctorid
fees
billdate
So far this is what I have:
select * from hospital where hospitalid =
(select hospitalid from doctor group by hospitalid having count ( doctorid ) =
(select max ( doctoramt ) from
(select count (doctorid) as doctoramt from doctor group by hospitalid) as tbltemp));
Try this but not tested
select * from hospital where hospitalid =
(select hospitalid from doctor group by hospitalid having count ( doctorid ) =
(select max ( doctoramt ) from
(select count (doctorid) as doctoramt from doctor group by hospitalid) as tbltemp)));
You can't use AS tbltemp to alias a table in Oracle. The AS keyword can only used to alias columns, not tables. You can either remove the AS keyword, or in this case since you don't refer to the alias, remove the whole AS tbltemp part. Here's an SQL Fiddle.
It looks like the parser initially tries to interpret AS as the alias name, and then doesn't know what the tbltemp is supposed to mean.
ZZa's approach is better anyway, but you could also use anayltic functions to avoid hitting the tables multiple times:
select hospitalid, hname, htype from (
select hospitalid, hname, htype, doc_count,
rank() over (order by doc_count desc) as rn
from (
select h.hospitalid, h.hname, h.htype,
count(d.doctorid) as doc_count
from hospital h
join doctor d on d.hospitalid = h.hospitalid
group by h.hospitalid, h.hname, h.htype
)
)
where rn = 1;
Another SQL Fiddle here. The innermost select does the counting, the next level ranks the grouped results in descending order of the number of doctors at each hospital, and the outermost restricts that to the highest-ranked.
Either way, if there's a tie - two hospitals with the same number of doctors - you'll get multiple rows back. If that's not what you want you'd need to decide how to break the tie.
Try this:
SELECT h.hospitalid, h.hname, h.htype
FROM hospital h, doctor d
WHERE h.hospitalid = d.hospitalid
GROUP BY h.hospitalid, h.hname, h.htype
HAVING COUNT(*) = (SELECT MAX(a) from (SELECT COUNT(*) a from doctor group by hospitalid));