我需要一些有关SQL查询的帮助。我有一个数据库表,该表具有与其他表相关的数据。当我查询表格时,它会为相关数据的每一行返回重复的行,即
|-------------| |-------------| |-------------|
| Cars | | Options | | Value |
|-------------| ------> |-------------| ------> |-------------|
| CarId | | OptionsId | | ValueId |
| CarMake | | OptionName | | CostValue |
| CarModel | | Confirmed | | CarId |
|-------------| | CarId | | OptionsId |
|-------------| |-------------|
|
|
---------------> |-------------|
| Warranty |
|-------------|
| WarrantyId |
| WarrantyType|
| CarId |
|-------------|
我所做的查询是在SSMS的查询生成器中设计的(因为它不使用别名并且具有3阶段命名约定,因此将被更改)如下:
SELECT dbo.Cars.CarId,
dbo.Cars.Make,
dbo.Cars.Model,
dbo.Options.OptionName,
dbo.Warranty.WarrantyType,
dbo.Value.CostValue
FROM dbo.Cars
LEFT JOIN dbo.Options ON dbo.Cars.CarId = dbo.Options.CarId
LEFT JOIN Value ON Options.OptionsId = Value.OptionsId
LEFT JOIN dbo.Warranty on dbo.Cars.CarId = dbo.Warranty.CarId
直接执行此查询会返回我的数据,但是,对于具有多个选项的汽车,我会收到重复的行,即
Id | Make | Model | Option Name | Warranty Type | Value
27 | Ford | Fiesta | Heated Seats | Static | 500
27 | Ford | Fiesta | Front Fog Lights | Static | 400
我一直在寻找这个问题的可能答案,发现建议的解决方案是使用关键字DISTINCT
或创建一个子查询。我在查询中添加了DISTINCT
,但返回了相同的数据,可能是因为选项本身是不同的,我不知道我在猜测什么。
我很高兴使用子查询,但是不确定如何将其应用于我上面的查询代码。我在这里要做的就是为每辆车返回最高选择值的单行。
27 | Ford | Fiesta | Heated Seats | Static | 500
有人可以帮我写这个查询吗?我想我已经把这个问题包括在内了,但是如果我能提供更多,请告诉我。
答案 0 :(得分:1)
而不是联接提供多行的表Value
,
您必须加入此查询:
SELECT
dbo.Value.CarId,
dbo.Value.OptionsId,
MAX(dbo.Value.CostValue) AS CostValue
FROM dbo.Value
GROUP BY dbo.Value.CarId, dbo.Value.OptionsId
您将从表Value
中为每辆车选择最大价值的选项。
所以试试这个:
SELECT dbo.Cars.CarId,
dbo.Cars.Make,
dbo.Cars.Model,
dbo.Options.OptionName,
v.CostValue,
dbo.Warranty.WarrantyType
FROM dbo.Cars
LEFT JOIN dbo.Options ON dbo.Cars.CarId = dbo.Options.CarId
INNER JOIN (
SELECT
dbo.Value.CarId,
dbo.Value.OptionsId,
MAX(dbo.Value.CostValue) AS CostValue
FROM dbo.Value
GROUP BY dbo.Value.CarId, dbo.Value.OptionsId
) AS v ON Options.OptionsId = v.OptionsId
LEFT JOIN dbo.Warranty on dbo.Cars.CarId = dbo.Warranty.CarId
答案 1 :(得分:0)
您可以使用窗口功能尝试以下操作
with cte as(
SELECT dbo.Cars.CarId,
dbo.Cars.Make,
dbo.Cars.Model,
dbo.Options.OptionName,
Value.CostValue,
row_number() over(partition by dbo.Cars.CarId,
dbo.Cars.Make,
dbo.Cars.Model order by Value.CostValue desc) rn
FROM dbo.Cars
LEFT JOIN dbo.Options ON dbo.Cars.CarId = dbo.Options.CarId
LEFT JOIN Value ON Options.OptionsId = Value.OptionsId
LEFT JOIN dbo.Warranty on dbo.Cars.CarId = dbo.Warranty.CarId
) select * from cte where rn=1