我正在加入3个表并得到错误的结果。目标是列出餐馆餐桌中的所有餐厅,如果评级存在,则显示任何餐厅的评级,否则显示为空,仅适用于汉堡的评级。
这是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'
结果如下:
然而'Cafe C'应该有Rating = null,因为我只想显示Burgers的评级。什么是正确的SQL?
用于创建表并填充数据的SQL语句:
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
答案 0 :(得分:3)
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'
答案 1 :(得分:2)
尝试:
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
答案 2 :(得分:1)
使用此查询:
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'
答案 3 :(得分:0)
这样的事情应该有效;在实际加入之前你需要删除“TACO” -
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
也许语法不完全正确,因为我没有SQL-Server来测试它,但是这个想法应该是这样的,并且像这样它在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"
答案 4 :(得分:0)
你在写一个外连接时遇到了问题所以这里有一个避免它们的替代方法(以及null值,外连接明确地设计为返回:)
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
);
答案 5 :(得分:-1)
尝试:
LEFT JOIN FoodType ft ON ft.FoodTypeID = cr.FoodTypeID WHERE
ft.FoodTypeID=1
思考可以帮助。