为什么我的T-SQL查询返回不一致的输出?

时间:2015-11-16 13:50:54

标签: sql-server tsql output behavior

我正在使用SQL Server 2014,我有以下T-SQL查询:

USE MyDatabase
GO

SELECT 
    a.ReservationStayID
    ,c.PMSConfirmationNumber
    ,c.[PropertyCode]
    ,a.StayDate
    ,c.[MTH]
    ,1 AS 'RN'
    ,a.PackagePlanCode
    ,c.[Market Segment Code]
    ,c.[Status]
    ,c.[CurrencyCode]
    ,a.RateAmount
    ,SUM(a.RateAmount) OVER (PARTITION BY a.ReservationStayID) AS 'CUM_Rate'
    ,d.[Exchange Rate]
    ,((a.RateAmount * d.[Exchange Rate]) / 1.15) AS 'Package Revenue Excl VAT'
    ,c.[Tour Operator]
    ,c.[Group Booking ID]
    ,c.[Source of Business]
    ,c.[Booking Origin (1)]
    ,c.[Market FINAL]
    ,ISNULL(ay.[KeyAccountName], 'NA') AS 'Key A/c'
    ,c.[CreatedOn_RSD]
FROM 
    ReservationStayDate a
INNER JOIN 
    [RESERVATIONLIST(2)] c ON c.[ReservationStayID] = a.ReservationStayID
                           AND c.[MTH] = datename(m, StayDate) + ' ' + cast(datepart(yyyy, StayDate) AS VARCHAR)
INNER JOIN 
    [PKGREVENUE] d ON d.[ReservationStayID] = a.ReservationStayID
                   AND d.[StayDate] = a.StayDate
ORDER BY 
    a.ReservationStayID;

查询运行正常,但输出不一致!有时,我得到698,017行,然后如果我立即再次运行查询,我可能得到698,020。另一次尝试显示698,025。

由于我的数据库尚未更新,这让我很生气。 SAME查询正在以1分钟的间隔运行,每次运行都会根据记录数提供不一致的输出!可能导致这种行为的原因是什么?

我不知道这些附加信息是否有任何帮助:

当我运行查询"按原样#34;上面,它给了我4条ReservationStayID = 147469的记录。

然后我将以下行添加到上述查询中作为过滤器:

WHERE a.ReservationStayID = 147469

令人惊讶的是,我只有2排!

[ReservationList(2)][PKGREVENUE]是观看次数。

以下是2个受欢迎的观点:

查看1:

CREATE VIEW [RESERVATIONLIST(2)] AS

SELECT 
   x.[ReservationStayID],
   b.PropertyCode,
   c.CreatedOn,
   c.CreatedBy,
   c.UpdatedBy,
   c.UpdatedOn,
   xy.Rooms AS [Room Inventory], --added
   (xy.Rooms*[DaysInMonth]) AS [RNAvailable], --added
   (x.[Nights Spent]/(xy.Rooms*[DaysInMonth])) AS [Occupancy],
   c.PMSConfirmationNumber,
   a.ArrivalDate AS [Arrival Date],
   a.DepartureDate AS [Departure Date],
   (a.ArrivalDate - CONVERT(Varchar(10),(CAST(x.CreatedOn as DATE)),(101))) AS 'Booking Lead Time',
    a.FirstName + ' ' + a.LastName AS 'Name',
    j.ProfileID,
    j.EmailAddress AS 'Email',
    b.MarketSegmentCode AS 'Market Segment Code',
    a.DateOfBirth AS 'Date of Birth',
    b.ReservationStatus AS 'Status',
    j.Nationality AS 'Nationality',
    k.[Country of Residence],
    ISNULL(g3.CountryGroup2, 'Not Specified') AS 'Country of Residence 2', 
     c.ReasonForStayCode AS 'Reason For Stay',
     b.RateplanCode,
     x.[Rate Plan RSD] AS 'Rate Plan Code',
     x.[Room Type RSD] AS 'Room Type',
     i.RoomType3 AS 'Room Type 3', -- this code converts the Room Type as per Room Type codes used in the Budget
     al.NonRoombundleID,
     k3.MpDescription AS 'Meal Plan Description',
     ISNULL(k3.MpCode,'RO') AS 'Meal Plan Code',
     x.[Adult RSD] AS 'Adult',
     x.[Child RSD] AS 'Child',
     b.GuestCount AS 'Total Guest',
     x.[Nights Spent] AS 'Room Nights',
     x.[MTH],
     x.[DaysInMonth], --added
     x.[Rate] AS 'Room Rate WITH VAT',
     c.CurrencyCode, 
     y.[Pkg Rev (with VAT)],
     y.[Pkg Rev (excl VAT)], 
    x.CreatedOn AS [CreatedOn_RSD],
    CONVERT(Varchar(10),(CAST(x.CreatedOn as DATE)),(101)) as [DATE CREATED ON],
    datename(m,x.CreatedOn) + ' ' + cast(datepart(yyyy,x.CreatedOn) as varchar) as [Created On (MTH)],
    x.[DateOfArrival],
    x.[DateOfDeparture],
    e.TravelAgencyTypeCode AS 'Source of Business',
    c.TAProfileID,
    c.PropGroupBookingID AS 'Group Booking ID', 
    e.Name AS 'Tour Operator', 
    g.CountryGroup AS 'Market', 
    c.TAProfileID2, 
    e2.Name AS 'Booking Origin (1)',
   g2.CountryGroup AS 'Booking Origin (2)', 

   (CASE
     WHEN e.TravelAgencyTypeCode = 'DMC' 
     THEN g2.CountryGroup 
     ELSE g.CountryGroup 
      END) AS 'Market (DMC Classified)',

   (CASE
     WHEN e.TravelAgencyTypeCode = 'DMC' THEN g2.CountryGroup
    WHEN c.TAProfileID = '316' AND c.CurrencyCode = 'MUR' THEN 'DB Local'
    WHEN c.TAProfileID = '316' THEN 'DB International'
    ELSE g.CountryGroup
    END) AS 'Market FINAL'

   FROM GuestNameInfo a

  JOIN GuestStaySummary b ON a.ReservationStayID = b.ReservationStayID
  LEFT JOIN ReservationStay c ON c.ReservationStayID =   b.ReservationStayID
  LEFT JOIN TravelAgency e ON e.TravelAgencyID = c.TAProfileID 
 LEFT JOIN Market g ON e.CountryCode = g.CountryCode
 LEFT JOIN TravelAgency e2 ON e2.TravelAgencyID = c.TAProfileID2
 LEFT JOIN Market g2 ON e2.CountryCode = g2.CountryCode

 LEFT JOIN CtyRes h ON h.ReservationStayID = a.ReservationStayID
 LEFT JOIN Market g3 ON g3.CountryCode = h.CountryCode

 LEFT JOIN Profile j ON j.ProfileID = c.ProfileID
 LEFT JOIN HotelInventory xy ON xy.PropertyCode = b.PropertyCode 



 LEFT JOIN
 (
    SELECT 
    min(CountryCode) AS [Country of Residence]
   , min(ProfileID) AS [Profile ID]
   ,min(PostalAddressID) AS [Postal Address ID]

   FROM PostalAddress
   GROUP BY CountryCode,ProfileID,PostalAddressID
  ) k ON k.[Postal Address ID] = c.PostalAddressID


 LEFT JOIN
  (
   SELECT 
     ReservationStayID,
     datename(m,StayDate) + ' ' + cast(datepart(yyyy,StayDate) as varchar) as [MTH],
     datediff(day, dateadd(day, 1-day(StayDate), StayDate),
          dateadd(month, 1, dateadd(day, 1-day(StayDate), StayDate))) AS [DaysInMonth],
     min(adultcount) as 'Adult RSD',
     min(childcount) as 'Child RSD',
     min(RoomTypeCode) AS 'Room Type RSD',
     min(PackagePlanCode) AS 'Rate Plan RSD',
     count(*) AS [Nights Spent],
     avg(RateAmount) as [Rate],
     min(CreatedOn) as CreatedOn,
     min(StayDate) as [DateOfArrival],
     max(StayDate) as [DateOfDeparture]
    FROM ReservationStayDate
    GROUP BY ReservationStayID, datename(m,StayDate) + ' ' +  cast(datepart(yyyy,StayDate) as varchar), datediff(day, dateadd(day, 1-day(StayDate), StayDate),
          dateadd(month, 1, dateadd(day, 1-day(StayDate), StayDate)))
 ) x ON x.ReservationStayID = b.ReservationStayID

 LEFT JOIN RoomCat i ON b.PropertyCode = i.Property AND [Room Type RSD] = i.RoomType


   LEFT JOIN

    (SELECT datename(m,StayDate) + ' ' + cast(datepart(yyyy,StayDate) as varchar) AS [MTH_PKGREV],
       [ReservationStayId], SUM([Package Revenue with VAT]) AS 'Pkg Rev (with VAT)',
       SUM([Package Revenue excl VAT]) AS 'Pkg Rev (excl VAT)'

   FROM PKGREVENUE

   GROUP BY datename(m,StayDate) + ' ' + cast(datepart(yyyy,StayDate) as varchar),[ReservationStayId]


   ) y ON y.[ReservationStayId] = b.ReservationStayID AND [MTH] = datename(m,[MTH_PKGREV]) + ' ' + cast(datepart(yyyy,[MTH_PKGREV]) as varchar)


  LEFT JOIN
   (
  SELECT ReservationStayID, MTH, NonRoombundleID

  FROM NONROOMBUNDLEID

  group by ReservationStayID, MTH, NonRoombundleID

  )al ON al.ReservationStayID = x.ReservationStayID AND al.[MTH] = x.[MTH]

  LEFT JOIN NonRoomBundle k2 ON K2.NonRoomBundleID = al.NonRoombundleID

  LEFT JOIN MealPlan k3 ON k3.MpDescription = k2.Description


  WHERE a.PrimaryGuest = '+'

观看2:

CREATE VIEW [PKGREVENUE] AS

SELECT
  ReservationStayDate.ReservationStayID AS [ReservationStayId]
  ,ReservationStay.PMSConfirmationNumber AS [PmsConfirmationNumber]
  ,ReservationStayDate.StayDate AS [StayDate]
  ,ReservationStayDate.RateAmount AS [RateAmount]
  ,ReservationStay.CurrencyCode AS [CurrencyCode]
  ,CAST(ROUND(ISNULL((1/CA.SellRate),1),2) as numeric (36,2)) AS 'Exchange Rate' -- since MUR is not in the Exchange Rate Table, this replaces all NULL values for MUR by 1.00

  ,CAST(ROUND(ReservationStayDate.RateAmount * ISNULL((1/CA.SellRate),1),0) as numeric (36,0)) AS 'Package Revenue with VAT'

  ,(CAST(ROUND(ReservationStayDate.RateAmount * ISNULL((1/CA.SellRate),1),0)/1.15 as numeric (36,0))) AS 'Package Revenue excl VAT'

FROM
  ReservationStayDate
  INNER JOIN ReservationStay ON ReservationStay.ReservationStayID = ReservationStayDate.ReservationStayID

  OUTER APPLY
  (
     SELECT TOP(1) ExchangeRate.SellRate
     FROM ExchangeRate
     WHERE
       ExchangeRate.ToCurrencyCode = ReservationStay.CurrencyCode
       AND ExchangeRate.EffectiveDate <= ReservationStayDate.StayDate
      ORDER BY ExchangeRate.EffectiveDate DESC
  ) AS CA

3 个答案:

答案 0 :(得分:1)

感谢所有为我的问题提供帮助的人。我甚至得到了否定,我不知道为什么! 无论如何,我想在这里提供一个更新,我是如何解决这个问题的。我深入研究了一些人所建议的确定性和非确定性函数。但是,我无法在查询和视图中找到导致主查询行为异常并给出不一致结果的任何此类函数。

我在主查询中尝试了GROUP BY子句(虽然我不需要该子句)。不料,问题解决了!!现在,我的查询在每次尝试时都给了我相同数量的记录。至于为什么GROUP BY子句解决了这个问题,我完全不知道。只想在这里与社区分享。可能有人可以阐明GROUP BY条款的神奇力量! : - )

答案 1 :(得分:0)

并非Sql Server中的所有函数都是确定性的。查看Deterministic and Nondeterministic Functions

我在查询中看不到任何不确定的内容,但您可能希望查看您加入的视图,并确保非确定性列表中没有任何内容。< / p>

答案 2 :(得分:0)

当包含以下内容的语句中混用或不一致使用别名时,总是会发生这种情况:

1-order by
2-group by
3-where clauses

喜欢这一行:

GROUP BY datename(m,StayDate) + ' ' + cast(datepart(yyyy,StayDate)

字段StayDate可能存在于查询的不同部分。有时,优化器采用不同的路径并选择其他字段。别名指示优化器始终采用适当的字段。