如何更好地编写此查询?

时间:2013-12-12 22:27:49

标签: sql sql-server-2008

我在这里有以下表格,需要将数据转换为略有不同。为了论证,这里是我正在使用的两个主要表格。

[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

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为你可以简化查询。以下内容汇总了车辆信息,以获取countprice和&#34;序列号&#34;每份合同中的每辆车。然后将合同信息加入,并汇总结果:

select c.ContractSummaries, c.ContractSummaryId,
       max(case when seqnum = 1 then VehicleDescription end) as VehicleType1Desc,
       max(case when seqnum = 1 then NumV end) as VehicleType1Count,
       max(case when seqnum = 1 then Price end) as VehicleType1Price,
       max(case when seqnum = 2 then VehicleDescription end) as VehicleType2Desc,
       max(case when seqnum = 2 then NumV end) as VehicleType2Count,
       max(case when seqnum = 2 then Price end) as VehicleType2Price,
       max(case when seqnum = 3 then VehicleDescription end) as VehicleType3Desc,
       max(case when seqnum = 3 then NumV end) as VehicleType3Count,
       max(case when seqnum = 3 then Price end) as VehicleType3Price
from Contracts c join
     (select cv.ContractId, cv.VehicleDescription, count(*) as NumV,
             sum(Price) as Price,
             row_number() over (partition by ContractId, VehicleDescription
                                order by count(*) desc
                               ) seqnum
      from ContractVehicles cv
      group by cv.ContractId, cv.VehicleDescription
     ) v
     on c.ContractId = v.ContractId
group by c.ContractId, c.ContractSummaries, c.ContractSummaryId;

我不清楚ContractIdContractSummaryId之间的关系 - 您对所需内容的描述是&#34;每份合同的车辆&#34;这就是它的作用。一个返回&#34;每个合同摘要的车辆的查询&#34;可能会有所不同。