SQL - Combining two queries - sql

I have these two Queries I'm trying to combine.
Query 1 - This tells me all the vehicles I have that are in my inventory. Meaning are not in the ownership table:
SELECT VEHICLE.*
FROM VEHICLE
WHERE NOT EXISTS
(SELECT NULL FROM OWNERSHIP WHERE VEHICLE.VEH_ID= OWNERSHIP.VEH_ID);
Query 2 - This one tells me which car is the highest priced for each brand.
SELECT B.BRAND_ID, B.BRAND_NAME, M.MODEL_NAME, C.CLASS_NAME, V.VEH_ID, V.VEH_YEAR, V.VEH_PRICE
FROM (((VEHICLE AS V INNER JOIN CLASS AS C ON V.CLASS_ID = C.CLASS_ID)
INNER JOIN MODEL AS M ON M.MODEL_ID = V.MODEL_ID)
INNER JOIN BRAND AS B ON B.BRAND_ID = M.BRAND_ID)
INNER JOIN (SELECT M.BRAND_ID, MAX(V.VEH_PRICE) AS VEH_PRICE FROM VEHICLE AS V
INNER JOIN MODEL AS M ON M.MODEL_ID = V.MODEL_ID GROUP BY M.BRAND_ID)
AS derived ON (v.VEH_PRICE = derived.VEH_PRICE) AND (b.BRAND_ID = derived.BRAND_ID)
ORDER BY 7 DESC;
I realized that determining which vehicles are the most expensive ones won't matter if they are already owned by a customer. Since the first query tells us which are available, how would I combine these two?

I couldn't test your query, but think this is what you are looking for:
SELECT
B.BRAND_ID,
B.BRAND_NAME,
M.MODEL_NAME,
C.CLASS_NAME,
V.VEH_ID,
V.VEH_YEAR,
V.VEH_PRICE
FROM
(((VEHICLE AS V INNER JOIN CLASS AS C ON V.CLASS_ID = C.CLASS_ID)
INNER JOIN MODEL AS M ON M.MODEL_ID = V.MODEL_ID)
INNER JOIN BRAND AS B ON B.BRAND_ID = M.BRAND_ID)
INNER JOIN (SELECT M.BRAND_ID, MAX(V.VEH_PRICE) AS VEH_PRICE
FROM VEHICLE AS V
INNER JOIN MODEL AS M
ON M.MODEL_ID = V.MODEL_ID
WHERE
NOT EXISTS
(SELECT NULL FROM OWNERSHIP
WHERE V.VEH_ID=OWNERSHIP.VEH_ID)
GROUP BY M.BRAND_ID) AS derived
ON (v.VEH_PRICE = derived.VEH_PRICE)
AND (b.BRAND_ID = derived.BRAND_ID)
WHERE
NOT EXISTS
(SELECT NULL FROM OWNERSHIP
WHERE V.VEH_ID=OWNERSHIP.VEH_ID)
ORDER BY 7 DESC;
You have to exclude cars already owned in the subquery where you calculate the maximum price for each brand, but also in the outer query, to exclude owned cars that have the same price as the maximum of cars that don't have an owner.
Instead of using NOT EXISTS clause, i would also suggest to add one more LEFT JOIN with OWNERSHIP both in the subquery and in the outer query, and to take only the rows where OWNERSHIP.VEH_ID is null.

Related

How to inner join with multiple tables for 3NF Normalization in SQL

I am trying to create normalization 3 nf (normal form) in this database. However, when I execute the query, the table is empty. As you will see, this is my table and diagram.
Here is the relationship that we want to 3NF
Torder->(Customer-Food-Carrier-Waiter)-(Ternary Relationship)-(Customer_id,Food_id,Carrier_id,Waiter_id)
Here is my query
SELECT
Customers.ID AS CustomerID,
Food.ID AS FoodID,
Carrier.ID AS CarrierID,
Waiter.ID AS WaiterID,
tOrder.ID AS TORDERID
FROM
tOrder
INNER JOIN
Customers ON Customers.ID = tOrder.Customer_id
INNER JOIN
Food ON Food.ID = tOrder.Food_id
INNER JOIN
Carrier ON Carrier.ID = tOrder.Carrier_id
INNER JOIN
Waiter ON Waiter.ID = tOrder.Waiter_id
ORDER BY tOrder.ID;
Clearly, you have an issue where some of the tables are empty or the ids do not match. You can use LEFT JOIN to keep all orders and see what is happening:
FROM tOrder o LEFT JOIN
Customers c
ON c.ID = o.Customer_id LEFT JOIN
Food f
ON f.ID = o.Food_id LEFT JOIN
Carrier ca
ON ca.ID = o.Carrier_id LEFT JOIN
Waiter w
ON w.ID = o.Waiter_id
If there are no matches, then the orders are still in the results, with NULL for the values in the table with no matches.
Note that this also introduces table aliases, so the query is easier to write and to read.

Joining tables and finding values that do not exist

I am having some issues with joining tables to get null values, and I can't find what I am doing wrong.
The case: I am trying to make a cinema system, where I have made entities that match the cinema.
I have a Hall, Row and Seat table, and a Show table that holds the value for movies and what hall it will be played in. To bond everything together, I have made a Reservation table that is keeping track of what seats to that specific show is taken.
My entities look like this:
My problem: I am trying to fetch all free seats for the show, I can get all seats for the show, but when I try to add the Reservation to get the free ones I get no records.
My query that is able to fetch all seats:
SELECT show.id AS ShowID,
seat.id AS SeatID,
seat.rowid AS RowID,
show.hallid AS HallId,
reservation.seatid AS Expr1
FROM show
INNER JOIN hall
ON show.hallid = hall.id
FULL OUTER JOIN seat
ON hall.id = seat.hallid
LEFT OUTER JOIN reservation
ON reservation.showid = show.id
WHERE ( show.id = 1 )
AND ( reservation.seatid IS NULL )
ORDER BY reservation.showid,
rowid
You need INNER joins between Show, Hall, Row and Seat and a LEFT join to Reservation, so you can filter out the matched rows:
SELECT s.Id AS ShowID, t.Id AS SeatID, t.RowId AS RowID, s.HallId
FROM Show s
INNER JOIN Hall h ON h.Id = s.HallId
INNER JOIN Seat t ON t.HallId = h.Id
INNER JOIN Row w ON w.HallId = h.Id AND w.Id = t.RowId
LEFT JOIN Reservation r ON r.ShowId = s.Id AND r.HallId = h.Id AND r.SeatId = t.Id AND r.RowId = w.Id
WHERE (s.Id = 1) AND (r.SeatId IS NULL)
Replace:
INNER JOIN Hall ON Show.Id = Hall.Id FULL OUTER JOIN
With:
INNER JOIN Hall ON Show.HallId = Hall.Id FULL OUTER JOIN
While it might not be the full answer to your question, i think this might cause issues for you too.

SQL query showing incorrect results

I am using Microsoft Access and I have this SQL query which does all the relevant joins:
SELECT c.ID
FROM ((((((((Cars c
INNER JOIN Offers
ON c.ID = Offers.car_id)
INNER JOIN Users u
ON c.owner_id = u.ID)
INNER JOIN City
ON u.city_id = City.ID)
INNER JOIN Models
ON c.model_id = Models.ID)
INNER JOIN Makes
ON Models.make_id = Makes.ID)
INNER JOIN Type
ON Models.type_id = Type.ID) ))
WHERE ( Offers.decision <> 3 )
In my Cars table I have 1 car and in my offers table I have 3 offers for the same car which have a Offers.decision of 2 and 4, for some reason when I execute the query it shows the same car 3 times like it is going on the basis of 3 offers.
Is their a way to show cars that do not have an Offers.decision of 3?
You should not use a join but a subquery:
SELECT * FROM Cars WHERE ID NOT IN (SELECT DISTINCT car_id FROM Offers WHERE decision <> 3)
Simplify your query to just:
SELECT c.ID
FROM Cars c INNER JOIN
Offers ON c.ID = Offers.car_id
WHERE (Offers.decision <> 3)

Issues with joining many tables getting to many values

This is my script:
select c.rendering_id as prov_number, c.begin_date_of_service as date_of_service,
c.practice_id as group_number, v.enc_nbr as invoice, p.person_nbr as patient,
v.enc_nbr as invoice_number, c.charge_id as transaction_number,
t.med_rec_nbr as primary_mrn, p.last_name, p.first_name,
z.payer_id as orig_fsc_number, z.payer_id as curr_fsc_number,
c.location_id as location_number, c.closing_date as posting_date,
c.quantity as service_units, c.amt as charge_amount,
c.cpt4_code_id as procedure_code, r.description as procedure_name,
x.tran_code_id as pay_code_number, ISNULL([modifier_1],'') as modifier_code_1,
ISNULL([modifier_2],'') as modifier_code_2, ISNULL([modifier_3],'') as modifier_code_3,
ISNULL ([icd9cm_code_id],'') as dx_code_1, ISNULL ([icd9cm_code_id_2],'') as dx_code_2,
ISNULL ([icd9cm_code_id_3],'') as dx_code_3, ISNULL ([icd9cm_code_id_4],'') as dx_code_4
from charges c, person p, patient t, patient_encounter v, encounter_payer z, cpt4_code_mstr r, transactions x
where c.person_id = p.person_id
and c.person_id = t.person_id
and c.person_id = v.person_id
and c.person_id = z.person_id
and c.cpt4_code_id = r.cpt4_code_id
and c.person_id = x.person_id
and c.practice_id = '0001'
and c.closing_date >= GetDate() - 7
I should be getting about 14k rows but with this I am getting a couple hundred thousand. I feel like there should be an inner join here to correct it but I have read through a bunch of posts and can seem to get it working. Its by far the biggest pull I have ever done in SQL.
Any help would be greatly help.
Without knowing more about the data structures and foreign key relationships, this answer is just educated speculation. Before answering, though, you need to learn proper JOIN syntax. Your query should look like:
from charges c join
person p
on . . . .
That said, you problem is probably that you are joining along multiple dimensions at the same time. Although not explicitly clear, I am guessing that a person could have multiple patient encounters, say A, B, and C. A person might also have multiple charges, say 10, 11, and 12.
Your query will produce nine rows in this case, one for each combination.
In other words, you need to identify:
Verify the join keys between tables. Is a table called transactions really joined to encounters and costs using the person_id?
Find out where you are getting cross products, and split into two subqueries that are then appropriately joined together.
I would suggest that you start with the first two tables, and see whether you get the expected row count for:
select *
from charges c join
person p
on c.person_id = p.person_id
where c.practice_id = '0001' and
c.closing_date >= GetDate() - 7
Then build up the query one table at a time to get the results you want.
One last note, when using table aliases, I find it much clearer to use aliases that evoke the table. "C" for charges is very good. Consider something like "pe" for patient_encounters, and so on.
It should be like this or you can use left join
select c.rendering_id as prov_number, c.begin_date_of_service as date_of_service,
c.practice_id as group_number, v.enc_nbr as invoice, p.person_nbr as patient,
v.enc_nbr as invoice_number, c.charge_id as transaction_number,
t.med_rec_nbr as primary_mrn, p.last_name, p.first_name,
z.payer_id as orig_fsc_number, z.payer_id as curr_fsc_number,
c.location_id as location_number, c.closing_date as posting_date,
c.quantity as service_units, c.amt as charge_amount,
c.cpt4_code_id as procedure_code, r.description as procedure_name,
x.tran_code_id as pay_code_number, ISNULL([modifier_1],'') as modifier_code_1,
ISNULL([modifier_2],'') as modifier_code_2, ISNULL([modifier_3],'') as modifier_code_3,
ISNULL ([icd9cm_code_id],'') as dx_code_1, ISNULL ([icd9cm_code_id_2],'') as dx_code_2,
ISNULL ([icd9cm_code_id_3],'') as dx_code_3, ISNULL ([icd9cm_code_id_4],'') as dx_code_4
from charges c
inner join person p on c.person_id = p.person_id
inner join patient t on c.person_id = t.person_id
inner join patient_encounter v on c.person_id = v.person_id
inner join encounter_payer z on c.person_id = z.person_id
inner join cpt4_code_mstr r on c.cpt4_code_id = r.cpt4_code_id
inner join transactions x on c.person_id = x.person_id
where c.practice_id = '0001'
and c.closing_date >= GetDate() - 7
Now you comment one inner join at a time and execute below query and see which of these joins is causing one to many relationship...when the count gives you say around 14 K that means the commented table is causing 1 to many relationship.
Otherwise best way is to find the relationship based on unique key,primary key and FK on these tables.
select
count(c.person_id)
from charges c
inner join person p on c.person_id = p.person_id
inner join patient t on c.person_id = t.person_id
inner join patient_encounter v on c.person_id = v.person_id
inner join encounter_payer z on c.person_id = z.person_id
inner join cpt4_code_mstr r on c.cpt4_code_id = r.cpt4_code_id
inner join transactions x on c.person_id = x.person_id
where c.practice_id = '0001'
and c.closing_date >= GetDate() - 7
You can try
select count(*) from <tablename> group by person_id having count(*) > 1
and repeat above query for all tables this will give you an idea on what kind of relationship between charges table and other tables. Offcourse use cpt4_code_id for cpt4_code_mstr table but by name it looks like that this table is master table so it will have a signle vale for each cpt4-code_id value in charges table.
I hope it will help

Query extensibility with WHERE EXISTS with a large table

The following query is designed to find the number of people who went to a hospital, the total number of people who went to a hospital and the divide those two to find a percentage. The table Claims is two million plus rows and does have the correct non-clustered index of patientid, admissiondate, and dischargdate. The query runs quickly enough but I'm interested in how I could make it more usable. I would like to be able to add another code in the line where (hcpcs.hcpcs ='97001') and have the change in percentRehabNotHomeHealth be relfected in another column. Is there possible without writing a big, fat join statement where I join the results of the two queries together? I know that by adding the extra column the math won't look right, but I'm not worried about that at the moment. desired sample output: http://imgur.com/BCLrd
database schema
select h.hospitalname
,count(*) as visitCounts
,hospitalcounts
,round(count(*)/cast(hospitalcounts as float) *100,2) as percentRehabNotHomeHealth
from Patient p
inner join statecounties as sc on sc.countycode = p.countycode
and sc.statecode = p.statecode
inner join hospitals as h on h.npi=p.hospitalnpi
inner join
--this join adds the hospitalCounts column
(
select h.hospitalname, count(*) as hospitalCounts
from hospitals as h
inner join patient as p on p.hospitalnpi=h.npi
where p.statecode='21' and h.statecode='21'
group by h.hospitalname
) as t on t.hospitalname=h.hospitalname
--this where exists clause gives the visitCounts column
where h.stateCode='21' and p.statecode='21'
and exists
(
select distinct p2.patientid
from Patient as p2
inner join Claims as c on c.patientid = p2.patientid
and c.admissiondate = p2.admissiondate
and c.dischargedate = p2.dischargedate
inner join hcpcs on hcpcs.hcpcs=c.hcpcs
inner join hospitals as h on h.npi=p2.hospitalnpi
where (hcpcs.hcpcs ='97001' or hcpcs.hcpcs='9339' or hcpcs.hcpcs='97002')
and p2.patientid=p.patientid
)
and hospitalcounts > 10
group by h.hospitalname, t.hospitalcounts
having count(*)>10
You might look into CTE (Common Table Expressions) to get what you need. It would allow you to get summarized data and join that back to the detail on a common key. As an example I modified your join on the subquery to be a CTE.
;with hospitalCounts as (
select h.hospitalname, count(*) as hospitalCounts
from hospitals as h
inner join patient as p on p.hospitalnpi=h.npi
where p.statecode='21' and h.statecode='21'
group by h.hospitalname
)
select h.hospitalname
,count(*) as visitCounts
,hospitalcounts
,round(count(*)/cast(hospitalcounts as float) *100,2) as percentRehabNotHomeHealth
from Patient p
inner join statecounties as sc on sc.countycode = p.countycode
and sc.statecode = p.statecode
inner join hospitals as h on h.npi=p.hospitalnpi
inner join hospitalCounts on t.hospitalname=h.hospitalname
--this where exists clause gives the visitCounts column
where h.stateCode='21' and p.statecode='21'
and exists
(
select p2.patientid
from Patient as p2
inner join Claims as c on c.patientid = p2.patientid
and c.admissiondate = p2.admissiondate
and c.dischargedate = p2.dischargedate
inner join hcpcs on hcpcs.hcpcs=c.hcpcs
inner join hospitals as h on h.npi=p2.hospitalnpi
where (hcpcs.hcpcs ='97001' or hcpcs.hcpcs='9339' or hcpcs.hcpcs='97002')
and p2.patientid=p.patientid
)
and hospitalcounts > 10
group by h.hospitalname, t.hospitalcounts
having count(*)>10