Reputation: 44225
I am joining between 3 tables and getting the wrong result. The goal is to list ALL the restaurants in the restaurants table and display the rating for any restaurant if the rating exists, otherwise display null, and only for ratings for burger.
This is the SQL:
SELECT r.RestaurantID, RestaurantName, cr.Rating FROM Restaurant r
LEFT JOIN CustRating cr ON cr.RestaurantID = r.RestaurantID
LEFT JOIN FoodType ft ON ft.FoodTypeID = cr.FoodTypeID AND
ft.FoodTypeName = 'Burger'
This is the result:
However 'Cafe C' should have Rating = null because I only want to display ratings for Burgers. What's the proper SQL?
The SQL Statements to create the tables and populate with data:
CREATE TABLE [dbo].[Restaurant](
[RestaurantID] [int] NOT NULL,
[RestaurantName] [varchar](250) NOT NULL
)
CREATE TABLE [dbo].[FoodType](
[FoodTypeID] [int] NOT NULL,
[FoodTypeName] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[CustRating](
[RestaurantID] [int] NOT NULL,
[FoodTypeID] [int] NOT NULL,
[Rating] [smallint] NOT NULL
)
BEGIN TRANSACTION;
INSERT INTO [dbo].[CustRating]([RestaurantID], [FoodTypeID], [Rating])
SELECT 2, 1, 3 UNION ALL
SELECT 3, 2, 2
COMMIT;
GO
BEGIN TRANSACTION;
INSERT INTO [dbo].[FoodType]([FoodTypeID], [FoodTypeName])
SELECT 1, N'Burger' UNION ALL
SELECT 2, N'Taco'
COMMIT;
GO
BEGIN TRANSACTION;
INSERT INTO [dbo].[Restaurant]([RestaurantID], [RestaurantName])
SELECT 1, N'Cafe A' UNION ALL
SELECT 2, N'Cafe B' UNION ALL
SELECT 3, N'Cafe C'
COMMIT;
GO
Upvotes: 2
Views: 130
Reputation: 4056
Something like this should work; You need to remove the "TACO"-row before actually join with it
SELECT r.RestaurantID, RestaurantName, crft.Rating
FROM Restaurant r
LEFT JOIN (SELECT cr.RestaurantID, cr.Rating
FROM CustRating cr JOIN FoodType ft
ON ft.FoodTypeID = cr.FoodTypeID
WHERE ft.FoodTypeName = 'Burger' ) as crft
ON crft.RestaurantID = r.RestaurantID
Maybe the Syntax is not completely right because I have no SQL-Server to test it, but the idea should be this, and like this it works perfektly on PostgreSQL
SELECT "r"."RestaurantID", "RestaurantName", "crft"."Rating"
FROM "Restaurant" r
LEFT JOIN (SELECT *
FROM "CustRating" cr JOIN "FoodType" ft
ON "ft"."FoodTypeID" = "cr"."FoodTypeID"
WHERE "ft"."FoodTypeName" = 'Burger' ) as crft
ON "crft"."RestaurantID" = "r"."RestaurantID"
Upvotes: 0
Reputation: 21776
Use this query:
SELECT DISTINCT
r.RestaurantID,
RestaurantName,
CASE WHEN ft.FoodTypeID IS NULL THEN NULL ELSE cr.Rating END Rating
FROM Restaurant r
LEFT JOIN CustRating cr ON cr.RestaurantID = r.RestaurantID
LEFT JOIN FoodType ft ON ft.FoodTypeID = cr.FoodTypeID AND
ft.FoodTypeName = 'Burger'
Upvotes: 1
Reputation: 57093
You are having problems writing an outer join so here's An alternative approach that avoids them (and the null value, which outer join is expressly designed to return :)
SELECT DISTINCT r.RestaurantID, r.RestaurantName,
N'Burger' AS FoodTypeName, cr.Rating
FROM dbo.Restaurant r
JOIN dbo.CustRating cr
ON r.RestaurantID = cr.RestaurantID
JOIN dbo.FoodType ft
ON ft.FoodTypeID = cr.FoodTypeID
AND ft.FoodTypeName = N'Burger'
UNION
SELECT DISTINCT r.RestaurantID, r.RestaurantName,
N'Burger' AS FoodTypeName, -1 AS Rating
FROM dbo.Restaurant r
WHERE NOT EXISTS (
SELECT *
FROM dbo.CustRating cr
JOIN dbo.FoodType ft
ON ft.FoodTypeID = cr.FoodTypeID
AND ft.FoodTypeName = N'Burger'
WHERE r.RestaurantID = cr.RestaurantID
);
Upvotes: 0
Reputation: 149
SELECT
Restaurant.*
,CASE WHEN FoodType.FoodTypeID IS NULL THEN NULL ELSE CustRating.Rating END AS Rating
FROM Restaurant Restaurant
LEFT OUTER JOIN CustRating CustRating
ON Restaurant.RestaurantID = CustRating.RestaurantID
LEFT OUTER JOIN FoodType FoodType
ON FoodType.FoodTypeID = CustRating.FoodTypeID
AND FoodType.FoodTypeName = 'Burger'
Upvotes: 3
Reputation: 1092
Try:
LEFT JOIN FoodType ft ON ft.FoodTypeID = cr.FoodTypeID WHERE
ft.FoodTypeID=1
Think could helps.
Upvotes: -1
Reputation: 37720
try :
SELECT r.RestaurantID, RestaurantName, T.Rating
FROM Restaurant r
LEFT JOIN (
select cr.RestaurantID, cr.Rating
from FoodType f
inner join CustRating cr on f.FoodTypeID = cr.FoodTypeID
where f.FoodTypeName = 'Burger'
) T on r.RestaurantID = t.RestaurantID
Upvotes: 2