i tried to figure out how to do the number 7 query on Helpdesk DB on SQLZOO (medium questions) but I can't. Not even using subquery or not exist statement. Here is the link (n. 7).
http://sqlzoo.net/wiki/Helpdesk_Medium_Questions
select first_name, last_name
from Caller a
left join Issue b
on a.Caller_id = b.Caller_id
where Call_date is null
This query says -
select ALL rows from Caller table regardless of them having a join
select ONLY rows from Issue where they have a join
Therefore, any row that returns from the Caller table that has not made a call will have a null value for Call_date. The where clause says only give me those rows.
You need to use LEFT JOIN on the Issue table and then add a filter where a field in the Issue table is null
SELECT ca.First_name, ca.Last_name
FROM Caller ca
LEFT JOIN Issue i ON ca.Caller_id = i.Caller_id
WHERE i.Caller_id is null
Related
Here is the T-SQL. The code has been around for years and it was handed to me to migrate to another SQL server. It apparently works, but I don't know why. The execution plan doesn't show any predicates being used, so how does it know which rows to exclude. If I run the subquery I get 1146 rows with the value 1
SELECT EM.PERSON_ID
FROM EMP_BEN_ELECTS EBE, EMPLOYEE_MAP EM
WHERE EBE.BW_ID = EM.BW_ID
AND CHANGE_BENEFIT_EVENT_DATE IS NULL
AND OPTION_ID <> 'WAIVE'
AND NOT EXISTS (SELECT 1 FROM EMPLOYEE_BILLING WHERE BILLING_GROUPING_ID
IN('HWMONTHLY','HWINDIVIDUALBILLED') AND END_DATE IS NULL)
I plan rewrite it without the subquery and use a left join instead, but this just boggled me that it works. The only time I seen code written like this without the join being qualified was when I seen code coming from an Oracle developer.
The subquery of NOT EXISTS is not used to return any (of the 1146) rows.
It is used to check if at least 1 row exists in the table EMPLOYEE_BILLING with the specified conditions:
BILLING_GROUPING_ID IN('HWMONTHLY','HWINDIVIDUALBILLED') AND END_DATE IS NULL
If there is such a row, then NOT EXISTS returns FALSE and since all the conditions in the WHERE clause of the main query are linked with the operator AND, then the final result is WHERE FALSE, making the query to not return any rows.
Don't rewrite the query with a LEFT join.
EXISTS and NOT EXISTS provide usually better performance than joins.
What you must change though, is that archaic join syntax with the ,.
Change it to a proper INNER join with an ON clause:
SELECT EM.PERSON_ID
FROM EMP_BEN_ELECTS EBE INNER JOIN EMPLOYEE_MAP EM
ON EBE.BW_ID = EM.BW_ID
WHERE CHANGE_BENEFIT_EVENT_DATE IS NULL
AND OPTION_ID <> 'WAIVE'
AND NOT EXISTS (
SELECT 1
FROM EMPLOYEE_BILLING
WHERE BILLING_GROUPING_ID IN('HWMONTHLY','HWINDIVIDUALBILLED')
AND END_DATE IS NULL
)
Also, you should qualify all the column names with the table's name/alias they belong to (CHANGE_BENEFIT_EVENT_DATE and OPTION_ID which I left unqualified because I don't know which alias to use).
I am making a subquery but I am getting a strange error
The column 'RealEstateID' was specified multiple times for 'NotSold'.
here is my code
SELECT *
FROM
(SELECT *
FROM RealEstatesInfo AS REI
LEFT JOIN Purchases AS P
ON P.RealEstateID=REI.RealEstateID
WHERE DateBought IS NULL) AS NotSold
INNER JOIN OwnerEstate AS OE
ON OE.RealEstateID=NotSold.RealEstateID
It's on SQL server by the way.
That's because there will be 2 realestiteids in your subquery. You need to change it to explicitly list the columns from both table and only include 1 realestateid. It doesn't matter which as you use it for your join.
If you're very Lazy you can select rei.* and only name the p cols apart from realestateid.
Btw select * is probably never a good idea in sub queries or derived tables or ctes.
My code is such:
SELECT COUNT(*)
FROM earned_dollars a
LEFT JOIN product_reference b ON a.product_code = b.product_code
WHERE a.activity_year = '2015'
I'm trying to match two tables based on their product codes. I would expect the same number of results back from this as total records in table a (with a year of 2015). But for some reason I'm getting close to 3 million.
Table a has about 40,000,000 records and table b has 2000. When I run this statement without the join I get 2,500,000 results, so I would expect this even with the left join, but somehow I'm getting 300,000,000. Any ideas? I even refered to the diagram in this post.
it means either your left join is using only part of foreign key, which causes row multiplication, or there are simply duplicate rows in the joined table.
use COUNT(DISTINCT a.product_code)
What is the question are are trying to answer with the tsql?
instead of select count(*) try select a.product_code, b.product_code. That will show you which records match and which don't.
Should also add a where b.product_code is not null. That should exclude the records that don't match.
b is the parent table and a is the child table? try a right join instead.
Or use the table's unique identifier, i.e.
SELECT COUNT(a.earned_dollars_id)
Not sure what your datamodel looks like and how it is structured, but i'm guessing you only care about earned_dollars?
SELECT COUNT(*)
FROM earned_dollars a
WHERE a.activity_year = '2015'
and exists (select 1 from product_reference b ON a.product_code = b.product_code)
I am having some problem when trying to perform a SQLite query to get the records which does not exist from another table. Basically I have two database tables:
My exercise table stored all the exercises available whereas the bookedExercise table store the exercises booked by each users. What I am trying to do is, for example if the exercise does exist in the bookedExercise, it should be filtered out.
Here is the SQLite query which I used:
SELECT exercise.exerciseID, exercise.exerciseType, exercise.amout FROM exercise LEFT JOIN bookedExercise WHERE exercise.exerciseID = bookedExercise.exerciseID AND bookedExercise.exerciseID IS NULL
However, it returned me empty records. Any ideas?
Thanks in advance.
If you're fine with not using joins you could use
SELECT * FROM exercise WHERE exerciseID not in (SELECT exerciseID FROM bookedExercise)
When you are using LEFT JOIN, you must put the join condition into the ON clause:
SELECT exercise.exerciseID,
exercise.exerciseType,
exercise.amout
FROM exercise /* !! */
LEFT JOIN bookedExercise ON exercise.exerciseID = bookedExercise.exerciseID
WHERE bookedExercise.exerciseID IS NULL
Your SQL looked okay... I think the problem might be you have a datatype mismatch. You have exercise ID as an integer in one table and text in another.
Also, if you have huge data volumes, you may want to consider an anti-join:
select
e.*
from
exercise e
where not exists (
select 1
from bookedExercise be
where
e.excerciseId = be.exerciseID
)
-- edit --
On second glance, your SQL was not okay. You had your join condition in the where clause. This little change would fix your existing SQL:
SELECT exercise.excerciseId , exercise.exerciseType , exercise.amout
FROM exercise LEFT JOIN bookedExercise on
exercise.excerciseId = bookedExercise.exerciseID
WHERE bookedExercise.exerciseID IS NULL
I have 2 sql tables mtblSite_Lavel_Budget and mtblExpenditure_Site_Lavel. I want to join them, so I wrote the query below, but one column always give null result although there are values in that field.
Query is as below
select mtblExpenditure_Site_Lavel.SFTI_Id,
mtblExpenditure_Site_Lavel.Site_Lavel_Interventions,
mtblExpenditure_Site_Lavel.Sub_Site_Lavel_Interventions,
mtblExpenditure_Site_Lavel.Bill_No, mtblExpenditure_Site_Lavel.Date_Of_Bill,
mtblExpenditure_Site_Lavel.Eligible_Exp,
mtblExpenditure_Site_Lavel.Non_Eligible_Exp,
mtblExpenditure_Site_Lavel.Total,
mtblExpenditure_Site_Lavel.Physical_Progress,
mtblSite_Lavel_Budget.Sanction_Amount_DPR
from mtblExpenditure_Site_Lavel
left join mtblSite_Lavel_Budget
on mtblExpenditure_Site_Lavel.Sub_Site_Lavel_Interventions= mtblSite_Lavel_Budget.Sub_Site_Lavel_Interventions
WHERE mtblExpenditure_Site_Lavel.SFTI_Id =13
ORDER BY Date_Of_Bill desc
and the result is as below
Please advise regarding the issue.
Try this
from mtblExpenditure_Site_Lavel left join mtblSite_Lavel_Budget on
mtblExpenditure_Site_Lavel.sfti_id = mtblSite_Lavel_Budget.sfti_id
I think its confused becouse you are joining on a string column its always best to join on the id where posible.