2012-11-28 49 views
2

我正在学习SQL Server查询考试,并从网站上获得了一些练习题的演示。其中一个问题要求从两个表格(CustomersOrders)中拉出,使用第一个初始值作为别名,为每个客户查找最近的订单,并使用最近的订单先订购。 Adventureworks有这样的表格(Sales.SalesOrderHeaderSales.Customer),所以我创建了这个查询并认为我已经解决了。将T-SQL查询转换为ANSI SQL-99标准

SELECT 
    c.CustomerID, 
    MAX(o.OrderDate) OVER (PARTITION BY c.customerid) AS MostRecentOrderDate 
FROM 
    Sales.SalesOrderHeader o 
INNER JOIN 
    Sales.Customer c ON o.CustomerID = c.CustomerID 
ORDER BY 
    OrderDate DESC 

但是......在问题结束时,它表示确保它符合ANSI SQL-99标准。

于是我查了

http://developer.mimer.com/validator/parser99/index.tml#parser

这段代码,它告诉我

以下功能核心SQL-99以外的使用:
T611,基本OLAP操作
F391,长识别码

这里的东西包含在T611基础OLAP操作的定义:

  • 窗口函数(ROW_NUMBER,RANK和DENSE_RANK)
  • 无名窗口规格:
    • 窗口分区(PARTITION BY)
    • 窗口排序(ORDER BY)
    • 窗框(ROWS/RANGE PRECEDING/FOLLOWING)
  • 空订货

我不知道,为什么我收到了“长标识符”的错误,但在这里是从微软有它的一些东西,一个链接的确切原因。

http://msdn.microsoft.com/en-us/library/hh544365(v=sql.105).aspx

IDK如果这实际上将帮助在考试或没有,但我感兴趣的答案。

+2

我不是ANSI 99标准的天才,但它不支持GROUP BY,JOIN + MAX ......你还需要什么来解决你的问题? – Najzero

+1

“使用Core SQL-99之外的以下功能:” - 这些功能是SQL-99的一部分。它们是可选的,因此实现不必支持它们。核心SQL-99是所有实现都需要支持的SQL-99位,但SQL-99远远超过了Core SQL-99,并且从您的问题中可以看出,您是否可以使用它。 – hvd

+0

感谢您的澄清,我不知道有什么不同。它没有在问题中指定。 – bpfrenchak

回答

3

以前接受的这个问题的答案时AdventureWorks示例数据库

列“SalesLT.SalesOrderHeader.OrderDate”上测试产生错误是在ORDER BY无效子句 ,因为它不包含在任一一个聚合函数或GROUP BY子句。

order by条款存在问题。 您可以通过使用

select C.LastName, max(O.OrderDate) as MROD 
from SalesLT.Customer C inner join SalesLT.SalesOrderHeader O 
on C.CustomerID = O.CustomerID 
group by C.LastName 
order by max(O.OrderDate) Desc 

select C.LastName, max(O.OrderDate) as MROD 
from SalesLT.Customer C inner join SalesLT.SalesOrderHeader O 
on C.CustomerID = O.CustomerID 
group by C.LastName 
order by MROD Desc 

修复这两个例子通过SQL-99验证测试,但只有当我用一个简短的名称,如MROD为最大(O .OrderDate)别名,而不是MostRecentOrderDate。

还有,我刚刚通过了考试。

+0

F391出现向后兼容性,可以安全地忽略。 SQL-89只允许标识符长达18个字符。 SQL-99允许标识符长度为128个字符。 – JamieSee

3

长标识符错误是由于标识符长度多于30个字符。 尝试此查询它的工作原理::

SELECT 
    c.CustomerID, 
    MAX(o.OrderDate) AS mrod 
FROM 
    SalesOrderHeader o 
INNER JOIN 
    Customer c ON o.CustomerID = c.CustomerID 
group by c.customerID 
ORDER BY 
    o.OrderDate DESC 
+0

+1只是在给定的SQL-99验证器中尝试了完全相同的东西,以确保 – Najzero

+0

有两个问题之一与标识符长度和另一个用法的分析功能 –

+0

有什么愚蠢的是,该问题要求具体名称'MostRecentOrderDate'为领域的名字。非常感谢!!! – bpfrenchak

0

尝试此查询:

select c.CustomerID, 
     MAX(o.OrderDate), 
from SalesOrderHeader o 
INNER JOIN Customer c ON o.CustomerID = c.CustomerID 
group by o.CustomerID 
ORDER BY 2 DESC 
+0

这将返回与原始查询不同的结果。 –

+0

我认为这也是对的。 – bpfrenchak

0

ORDER BY是一个基本OLAP操作。您可以安全地将其删除,您的数据可能无法以您喜欢的方式显示。

长标识符错误是因为您引用了INFORMATION_SCHEMA.INFORMATION_SCHEMA_CATALOG_NAME。换句话说,你的Sales.SalesOrderHeader位。您应该只能引用信息模式目录名称,在您的情况下为SalesOrderHeaderCustomer,而不指定Sales.

0

通过SQL-99他们可能只是意味着用户INNER JOIN和ON而不是加入WHERE子句。