SQL Server:使用TOP或Order By时查询失败

时间:2014-10-20 20:47:56

标签: sql-server sql-server-2008-r2

此查询返回正确的结果。

SELECT 
   a.Company, a.FiscalYear, a.FiscalPeriod,
   a.JournalCode, a.JournalNum, a.JournalLine, a.Description,
   a.JEDate, a.GroupID, a.PostedBy, a.PostedDate,
   a.SourceModule,
   b_1.PartDescription, b_1.PartNum, b_1.PONum,
   b_1.POLine, b_1.VendorID, b_1.VendorNum, b_1.VendorName
FROM   
   epicor905.dbo.GLJrnDtl AS a
LEFT OUTER JOIN 
   (SELECT 
       a.Company, a.TranNum, a.TranDate, a.PartNum, a.WareHouseCode, a.TranQty,
       a.MtlUnitCost, a.ExtCost, a.PONum, a.POLine, a.PORelNum, a.PartDescription,
       a.VendorNum, c.VendorID, c.Name AS VendorName, a.POUnitCost, a.POReceiptQty,
       a.GLTrans, a.PostedToGL, b.JournalNum, b.JournalLine, b.JournalCode, 
       b.FiscalYear
    FROM   
       epicor905.dbo.PartTran AS a
    INNER JOIN 
       epicor905.dbo.TranGLC AS b ON a.Company = b.Company
                                  AND a.SysDate_ = b.Key1
                                  AND a.SysTime = b.Key2
                                  AND a.TranNum = b.Key3
    LEFT OUTER JOIN 
       epicor905.dbo.Vendor AS c ON a.Company = c.Company
                                 AND a.VendorNum = c.VendorNum
    WHERE  
       (b.RelatedToFile = 'PartTran')
       AND (a.PostedToGL = 1 )) AS b_1 ON a.Company = b_1.Company
                                        AND a.JournalCode = b_1.JournalCode
                                        AND a.FiscalYear = b_1.FiscalYear
                                        AND a.JournalNum = b_1.JournalNum
                                        AND a.JournalLine = b_1.JournalLine
WHERE  
    (a.FiscalYear = 2014)

以下查询不起作用。

他们都失败了

  

从字符串转换日期和/或时间时转换失败。

我尝试在ISDATE(col) == 1条款中使用JOIN,但它似乎没有帮助。

添加了TOP(10)

SELECT TOP(10) a.Company,a.FiscalYear,a.FiscalPeriod,a.JournalCode,a.JournalNum,a.JournalLine,a.Description,
              a.JEDate,a.GroupID,a.PostedBy,a.PostedDate,a.SourceModule,b_1.PartDescription,b_1.PartNum,b_1.PONum,
              b_1.POLine,b_1.VendorID,b_1.VendorNum,b_1.VendorName
FROM   epicor905.dbo.GLJrnDtl AS a
       LEFT OUTER JOIN (SELECT a.Company,a.TranNum,a.TranDate,a.PartNum,a.WareHouseCode,a.TranQty,a.MtlUnitCost,a.ExtCost,
                               a.PONum,a.POLine,a.PORelNum,a.PartDescription,a.VendorNum,c.VendorID,c.Name AS VendorName,
                               a.POUnitCost,a.POReceiptQty,a.GLTrans,a.PostedToGL,b.JournalNum,b.JournalLine,b.JournalCode,b.FiscalYear
                        FROM   epicor905.dbo.PartTran AS a
                               INNER JOIN epicor905.dbo.TranGLC AS b
                                       ON a.Company = b.Company
                                          AND a.SysDate_ = b.Key1
                                          AND a.SysTime = b.Key2
                                          AND a.TranNum = b.Key3
                               LEFT OUTER JOIN epicor905.dbo.Vendor AS c
                                            ON a.Company = c.Company
                                               AND a.VendorNum = c.VendorNum
                        WHERE  ( b.RelatedToFile = 'PartTran' )
                               AND ( a.PostedToGL = 1 )) AS b_1
                    ON a.Company = b_1.Company
                       AND a.JournalCode = b_1.JournalCode
                       AND a.FiscalYear = b_1.FiscalYear
                       AND a.JournalNum = b_1.JournalNum
                       AND a.JournalLine = b_1.JournalLine
WHERE  ( a.FiscalYear = 2014 )

添加订单

SELECT a.Company,a.FiscalYear,a.FiscalPeriod,a.JournalCode,a.JournalNum,a.JournalLine,a.Description,
       a.JEDate,a.GroupID,a.PostedBy,a.PostedDate,a.SourceModule,b_1.PartDescription,b_1.PartNum,b_1.PONum,
       b_1.POLine,b_1.VendorID,b_1.VendorNum,b_1.VendorName
FROM   epicor905.dbo.GLJrnDtl AS a
       LEFT OUTER JOIN (SELECT a.Company,a.TranNum,a.TranDate,a.PartNum,a.WareHouseCode,a.TranQty,a.MtlUnitCost,a.ExtCost,
                               a.PONum,a.POLine,a.PORelNum,a.PartDescription,a.VendorNum,c.VendorID,c.Name AS VendorName,a.POUnitCost,
                               a.POReceiptQty,a.GLTrans,a.PostedToGL,b.JournalNum,b.JournalLine,b.JournalCode,b.FiscalYear
                        FROM   epicor905.dbo.PartTran AS a
                               INNER JOIN epicor905.dbo.TranGLC AS b
                                       ON a.Company = b.Company
                                          AND a.SysDate_ = b.Key1
                                          AND a.SysTime = b.Key2
                                          AND a.TranNum = b.Key3
                               LEFT OUTER JOIN epicor905.dbo.Vendor AS c
                                            ON a.Company = c.Company
                                               AND a.VendorNum = c.VendorNum
                        WHERE  ( b.RelatedToFile = 'PartTran' )
                               AND ( a.PostedToGL = 1 )) AS b_1
                    ON a.Company = b_1.Company
                       AND a.JournalCode = b_1.JournalCode
                       AND a.FiscalYear = b_1.FiscalYear
                       AND a.JournalNum = b_1.JournalNum
                       AND a.JournalLine = b_1.JournalLine
WHERE  ( a.FiscalYear = 2014 )
ORDER  BY a.JournalNum 

此外还有来自epicor的一些信息。

Summary:        XA How to determine Key fields in TranGLC table?
Book:           Support Solutions
Page:           10175MPS

PAGE:  10175MPS  Updated: 11/21/2012

PROBLEM:
XA How to determine Key fields in TranGLC table?  The fields will be different depending on the TranGLC.RelatedToFile.

RESOLUTION:
In order to determine this, you need to find the Primary Index for the RelatedToFile's table.

1. Open Data Dictionary Viewer
2. Tools > Personalization
3. Click in the Indexes grid and select the pulldown on the "Collections" and uncheck the "Hidden" checkbox for PrimaryIndex
4. Select the RelatedToFile table in the Data Dictionary
5. View the Primary Index for that table
**The Key fields will be listed in order separated by a comma.  The Company field is not included as the first Key field in the TranGLC table, so that field can be ignored.**

Example:
TranGLC.RelatedToFile = PartTran
The Primary Index for PartTran = sysdttime
*Note the Index fields for the primary index (Company,SysDate,SysTime,TranNum)*
**Company will not be one of the Key fields**
Key1 = SysDate
Key2 = SysTime
Key3 = TranNum

VERSION:
9.04.503

2 个答案:

答案 0 :(得分:2)

查询失败与TOPORDER BY无关。问题在于,在此查询的某个位置,您正在比较或加入一个类型为DATETIME的列和另一个类型为(N)VARCHAR的列,而后一列包含一个无法转换为{{ 1}}。通过添加DATETIMETOP,优化器只是构建一个不同的执行计划来公开有问题的数据 - 第一个查询在没有遇到麻烦的行的情况下工作是纯粹的运气。

您可以包含表格的模式吗?如果您知道有问题的列,则可以通过在ORDER BY中明确地将DATETIME列转换为VARCHAR(即JOIN或其他任何格式来修复转换问题适当的)所以引擎并没有尝试反过来做失败。

答案 1 :(得分:1)

问题是优化引擎有时候在转换之前不会费心去查看WHERE。在过去,您必须进行子查询以仅选择具有正确类型的项目,然后在外部选择中进行强制转换(可能更慢)。

但是,较新版本的SQL包括TRY_CAST。现在,您可以在join语句中使用TRY_CAST。当它无法转换时,此函数返回null,因此它不会阻止查询仅运行该行的连接 - 这是所需的行为。应该没有问题使用它。

像这样:

SELECT    
  a.Company, a.FiscalYear, a.FiscalPeriod, a.JournalCode, a.JournalNum, a.JournalLine, a.Description, a.JEDate, a.GroupID, a.PostedBy, 
  a.PostedDate, a.SourceModule, b_1.PartDescription, b_1.PartNum, b_1.PONum, b_1.POLine, b_1.VendorID, b_1.VendorNum, b_1.VendorName
FROM epicor905.dbo.GLJrnDtl AS a 
LEFT OUTER JOIN
  (SELECT
     a.Company, a.TranNum, a.TranDate, a.PartNum, a.WareHouseCode, a.TranQty, a.MtlUnitCost, a.ExtCost, a.PONum, a.POLine, a.PORelNum, 
     a.PartDescription, a.VendorNum, c.VendorID, c.Name AS VendorName, a.POUnitCost, a.POReceiptQty, a.GLTrans, a.PostedToGL, b.JournalNum, 
     b.JournalLine, b.JournalCode, b.FiscalYear
   FROM epicor905.dbo.PartTran AS a 
   INNER JOIN epicor905.dbo.TranGLC AS b 
      ON a.Company = b.Company AND a.SysDate_ = TRY_CAST(b.Key1 AS DATE) AND a.SysTime = TRY_CAST(b.Key2 AS TIME) AND a.TranNum = b.Key3 
   LEFT OUTER JOIN epicor905.dbo.Vendor AS c 
      ON a.Company = c.Company AND a.VendorNum = c.VendorNum
   WHERE
     (b.RelatedToFile = 'PartTran') AND (a.PostedToGL = 1)
  ) AS b_1 
   ON  a.Company = b_1.Company 
   AND a.JournalCode = b_1.JournalCode 
   AND a.FiscalYear = b_1.FiscalYear 
   AND a.JournalNum = b_1.JournalNum 
   AND a.JournalLine = b_1.JournalLine
WHERE     (a.FiscalYear = 2014)

部分兴趣:

... a.SysDate_ = TRY_CAST(b.Key1 AS DATE) AND a.SysTime = TRY_CAST(b.Key2 AS TIME) ...

Microsoft参考文档: http://msdn.microsoft.com/en-us/library/hh974669.aspx