0
我在这里有以下工作表,需要转换数据看起来有点不同。为了参数,这里是我正在使用的两个主表。如何更好地编写此查询?
[dbo].[Contracts](
[ContractId] [int]
<Some Other Fields>
)
[dbo].[ContractVehicles](
[ContractVehicleId] [int]
[ContractId] [int] **(FK to Contracts)**,
[VehicleDescription] [varchar],
[Price] [int]
)
如您所见,有合同和合同工具。合同可以有许多车辆与之相关联。
我想一个表,如下所示:
[dbo].[ContractSummaries](
[ContractSummaryId] [int] **(just this table's seed)**,
[ContractId] [int]
[VehicleType1Desc] [varchar],
[VehicleType1Count] [int],
[VehicleType1TotalPrice] [int],
[VehicleType2Desc] [varchar],
[VehicleType2Count] [int],
[VehicleType2TotalPrice] [int],
[VehicleType3Desc] [varchar],
[VehicleType3Count] [int],
[VehicleType3TotalPrice] [int]
)
基本上,我想列出一份合同,直到与该合同相关联的第3个车型,以#沿表这种类型的车辆,以及该类型的总价格。
为了达到这个目的,我写下了下面的查询。有没有更简洁和有效的方式来写这个? 请注意,我提供的结构或查询都不是实际的查询,我可能在这些表示中出现语法错误。我对此表示歉意,希望这些例子能成功证明我的意图。
SELECT
ContractId,
(
SELECT
VehicleDescription
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 1
) VehicleType1Desc,
(
SELECT
NumVehicle
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 1
) VehicleType1Count,
(
SELECT
TotalVehicleTypePrice
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 1
) VehicleType1TotalPrice,
(
SELECT
VehicleDescription
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 2
) VehicleType2Desc,
(
SELECT
NumVehicle
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 2
) VehicleType2Count,
(
SELECT
TotalVehicleTypePrice
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 2
) VehicleType2TotalPrice,
(
SELECT
VehicleDescription
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 3
) VehicleType3Desc,
(
SELECT
NumVehicle
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 3
) VehicleType3Count,
(
SELECT
TotalVehicleTypePrice
(
SELECT
ROW_NUMBER() OVER (ORDER BY COUNT(VehicleDescription), ContractId ASC) as rownumber,
VehicleDescription,
COUNT(v.VehicleDescription) NumVehicle,
SUM(Price) TotalVehicleTypePrice
FROM
Contracts c INNER JOIN ContractVehicles v on c.ContractId = v.ContractId
WHERE
c.ContractId = cOuter.ContractId
GROUP BY
v.ContractID,
v.VehicleDescription
) countTable
WHERE
rowNumber = 3
) VehicleType3TotalPrice,
FROM
Contracts outerC
谢谢!
感谢您的帮助,这让事情变得更加清晰。不知道为什么我决定我需要使用子查询。有一件事我不清楚在你的例子中,是max()在select中的每一列上完成的。在我明天上午把这个转化为实际的查询之后,我一定会把它作为正确的。 –
@DavidGutierrez你也可以使用MIN而不是MAX。这是由于group by子句造成的一个技巧。否则这个查询将不可执行。 –
将row_number()分区调整为不包含车辆描述后,该功能非常有效。再次感谢。 –