SQL Server count() returns different results when using joins - sql

I am new to SQL Server and I am not looking for a solution (but it may help others), rather, I would like to understand the behaviour / why I get two different results from the two pseudo queries below.
The reason I have joined two other tables is because I will need to count all items in Vehicle against the 'Date_Recorded' in 'Garage'. All recorded since 2010. So before I did this I wanted to be sure I was getting the same total count from the table 'Car' and also get the same result with the joins, before I added the 'isDate' on 'Garage' condition, that is when I noticed the difference in the results.
I would have thought the joins would have been ignored?
Hope someone can advise? Thanks in advance!
SELECT count(Car.CAR_ID) AS Car_ID
FROM Vehicle Car
INNER JOIN Road Rd
ON Car.CAR_ID = Rd.CAR_ID
JOIN Garage g
ON Rd.GARAGE_ID = g.GARAGE_ID
----------------------------------------------
Car_ID
----------------------------------------------
226923
SELECT count(Car.CAR_ID) AS Car_ID
FROM Vehicle Car
----------------------------------------------
Car_ID
----------------------------------------------
203417

INNER JOIN: Returns all rows when there is at least one match in BOTH tables.
LEFT JOIN: Return all rows from the left table, and the matched rows from the right table.
RIGHT JOIN: Return all rows from the right table, and the matched rows from the left table.
FULL JOIN: Return all rows when there is a match in ONE of the tables.
you are using inner join thats why you are getting the wrong result from the actual count() result.
if you want to get all the record from the left table the you have to use left join in this query then you'll get the result of count() same as the main table[left table].

You either have
multiple records in the Road table with the same Car_ID or
multiple records in the Road table with the same Garage_ID or
Both of the above
You may be able to run the following to get what you want (assuming there is always a match in the road and garage tables):
SELECT count(Distinct Car.CAR_ID) AS Car_ID
FROM Vehicle Car
INNER JOIN Road Rd
ON Car.CAR_ID = Rd.CAR_ID
JOIN Garage g
ON Rd.GARAGE_ID = g.GARAGE_ID

Related

SQL queries: how to get the value which appears the most in the total of two different tables?

Context: I want to know which vehicle brand appears the most in different accidents.
I have the table vehicle (v_number, brand).
Problem is, I have two different accident tables:
One refers to driven cars involved in an accident, let's call it acc_drive (v_number, acc_number, driver) [v_number FK vehicle]
The other refers to parked cars which are involved in an accident, let's call it acc_park (v_number, acc_number) [v_number FK vehicle, acc_number FK acc_drive]
Now, I'm trying to get the vehicle brand which appears the most in the total of the two tables. For example, if Audi cars appeared 2 times in acc_drive and 3 times in acc_park, the total number of appearences would be 5.
I'm having a really hard time trying to figure this out, so a helping hand would be much appreciated!
UNION ALL can be used to bring the tables together for the JOIN:
select v.brand, count(a.v_number)
from vehicle v left join
((select v_number
from acc_drive
) union all
(select v_number
from acc_park
)
) a
on v.v_number = a.v_number
group by v.brand
order by count(v_number) desc; -- put the biggest numbers first
Note that this uses a left join. So brands with no accidents will be included in the results.
Try this-
SELECT TOP 1 brand,COUNT(*)
FROM vehicle A
INNER JOIN acc_drive B ON A.v_number = B.v_number
INNER JOIN acc_park C ON A.v_number = C.v_number
GROUP BY brand
ORDER BY COUNT(*) DESC

Parent child relationship Join tables in oracle sql

I have a requirement below.
Now I have to get output like below
How can this be achieved ?
I have written the below SQL but parent_position_id is coming, not parent_position_code
select
hapf.position_code,
pphf.parent_position_id
from
hr_all_positions_f hapf, PER_POSITION_HIERARCHY_F pphf
where
hapf.position_id = pphf.position_id
Should I write a sub query? How should I proceed ?
This is Oracle SQL
Thanks,
Shivam
Noone ever said you could only join a table in once:
select
chi.position_code,
par.position_code as parent_position_code
from
hr_all_positions_f hapf
INNER JOIN PER_POSITION_HIERARCHY_F chi on hapf.position_id = chi.position_id
INNER JOIN PER_POSITION_HIERARCHY_F par on hapf.parent_position_id = par.position_id
Bear it in mind; I see people coming to thinking all the time that they can only join a table once. If one table decodes a value in 3 different columns, then you sure can join that same table in 3 times... Imagine if it were an address table, and a Student had a HomeAddressId, WorkAddressId and StudyAddressId, and the Address table held all these addresses - you'd join the addresses table to the Student table 3 times to get all the data..

Select distinct record with join count records

I have two tables: Company and Contact, with a relationship of one-to-many.
I have another table Track which identifies some of the companies as parent companies to other companies.
I want to write a SQL query that selects the parent companies from Track and the amount of contacts that each parent has.
SELECT Track.ParentId, Count(Contact.companyId)
FROM Track
INNER JOIN Contact
ON Track.ParentId = Contact.companyId
GROUP BY Track.ParentId
however The result holds less records than when I run the following query:
SELECT DISTINCT Track.ParentId
FROM Track
I tried the first query with an added DISTINCT and it returned the same results (less then what it was meant to).
You're performing an INNER JOIN with the Contact table, which means that any rows from the first table (Track in this case) with no matches to the JOINed table will not show up in your results. Try using a LEFT OUTER JOIN instead.
The COUNT with Contact.companyId will only count rows where there is a match (Contact.companyId is not NULL). Since you're counting contacts that's fine as they will count as 0. If you were trying to count some other set of data and tried to do a COUNT on a specific column (rather than COUNT(*)) then any NULL values in that column would not count towards your total, which might or might not be what you want.
I used an INNER JOIN which returns only records that are identical in both tables.
To return all records from Track table, and records that match in the Contact table, I need to use LEFT JOIN.

how to join one table to multiple other tables

i have a query which is used to generate reports. There are multiple fields to be displayed. One requirement is such that i need to join one table to different tables with different aliases for data. e.g., table 1 employee id with employee table for knowing the full name. similarly table 2 employee id with employee table for table 2 employee id full name. PFB the query:
select * from office o
left join employee e
on e.id=o.id
left join master m
on m.id=o.id
left join student s1
on e.id=s1.id
left join student s2
on m.id=s2.id
Can we optimize this query to use only one join statement of student table instead of multiple table join statement? I need to reduce the number of tables used in the query since i'm getting the error as too many tables in the query maximum allowed is 50. Please help. Appreciate.
Can we optimize this query to use only one join statement of student
table instead of multiple table join statement?
No, I would not call it query optimization. However, for reporting purposes you reduce the joins by creating views.
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc00801.1510/html/iqrefso/X315714.htm

SQL like clause is not returning any results

I have following query, but it doesn't return any results for where clauses, even when there is row with that kind of name what is queried. If I remove where clause, then all records in Company table which have OfficeLocation table are returned. What is wrong in my query?
SELECT c.*
FROM [MyDb].[dbo].[Company] AS c
INNER JOIN [MyDb].[dbo].[CompanyOfficeLocation] AS col ON c.Id = col.CompanyId
INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
WHERE ol.Name like '%Actual Name In This Table%';
Table structure :
Company
Id
etc ...
CompanyOfficeLocation
CompanyId
OfficeLocationId
OfficeLocation
Id
etc ...
Two things for a record to show up given your query:
The OfficeLocation you specified (given the ol.Name value) must have an Id value that is used by a record in the CompanyOfficeLocation table in its OfficeLocationId.
The CompanyOfficeLocation record that you got in #1 must have a CompanyId that exists in the Company table.
If any of those two criteria are not met, then no records will show up in your query result. The INNER JOIN is essentially an 'AND' clause. If a record could not be related to at least one INNER JOINed table, then that record will not show up at all.
If you want a record to show up despite not having any related records in the joined tables, you may want to consider using OUTER JOINs. A RIGHT JOIN in your case to be exact.
I do not find any mistake however I'd suggest you switch the columns after ON when joining to maintain standards.
Instead of - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
Do - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON col.OfficeLocationId = ol.Id