无法保存查看中的查询

时间:2015-03-27 07:19:37

标签: sql-server-2008

我尝试使用新代码更改现有视图:

with cte1 as (
SELECT    dbo.T_ActionTicketLog.ID, dbo.T_ActionTicketLog.ActionTicketID, dbo.T_Action.Artist, dbo.T_ActionTickets.ActionDate, dbo.T_ActionSeatsType.SeatType,
         dbo.T_ActionPlaceSeats.Seats, dbo.T_ActionTickets.RowNumber, dbo.T_ActionTickets.SeatNumber, dbo.T_ActionTickets.Price, dbo.T_TicketStatus.Name AS Status,
         dbo.T_Users.UserName, dbo.T_OrderTicket.OrderID, T_Users_1.UserName AS SalerName, dbo.T_Fiscal.DocNum, dbo.T_FiscalType.Name AS DocType,
         dbo.T_ActionTicketLog.TicketOrderID, dbo.T_ActionTicketLog.StatusID, dbo.T_ActionTicketLog.UserID, dbo.T_ActionTicketLog.SalerID, dbo.T_ActionTicketLog.FiscalID,
         dbo.T_ActionTicketLog.BarCode, dbo.T_ActionTicketLog.ReservDate, dbo.T_ActionTicketLog.Created, dbo.T_ActionTicketLog.Comments,
         CASE WHEN StatusID IN (3, 10) THEN 1 ELSE 0 END
         * ROW_NUMBER() OVER (PARTITION BY T_ActionTicketLog.ActionTicketID, T_ActionTicketLog.StatusID ORDER BY T_ActionTicketLog.Created) AS rn
FROM          dbo.T_Users AS T_Users_1 RIGHT OUTER JOIN
         dbo.T_ActionPlaceSeats INNER JOIN
         dbo.T_ActionTicketLog INNER JOIN
         dbo.T_TicketStatus ON dbo.T_ActionTicketLog.StatusID = dbo.T_TicketStatus.ID INNER JOIN
         dbo.T_Action INNER JOIN
         dbo.T_ActionTickets ON dbo.T_Action.ID = dbo.T_ActionTickets.ActionID INNER JOIN
         dbo.T_ActionSeatsSubType ON dbo.T_ActionTickets.ActionSeatsSubTypeID = dbo.T_ActionSeatsSubType.ID ON 
         dbo.T_ActionTicketLog.ActionTicketID = dbo.T_ActionTickets.ID INNER JOIN
         dbo.T_ActionSeatsType ON dbo.T_ActionSeatsSubType.SeatsTypeID = dbo.T_ActionSeatsType.ID ON 
         dbo.T_ActionPlaceSeats.ID = dbo.T_ActionSeatsType.SeatsID LEFT OUTER JOIN
         dbo.T_Users ON dbo.T_ActionTicketLog.UserID = dbo.T_Users.ID ON T_Users_1.ID = dbo.T_ActionTicketLog.SalerID LEFT OUTER JOIN
         dbo.T_FiscalType INNER JOIN
         dbo.T_Fiscal ON dbo.T_FiscalType.ID = dbo.T_Fiscal.FiscalTypeID ON dbo.T_ActionTicketLog.FiscalID = dbo.T_Fiscal.ID LEFT OUTER JOIN
         dbo.T_OrderTicket ON dbo.T_ActionTicketLog.TicketOrderID = dbo.T_OrderTicket.ID
),
cte2 as (
   SELECT ActionTicketID, OrderTicketID, Created, TicketBarCode,
   ROW_NUMBER() OVER (PARTITION BY ActionTicketID ORDER BY Created) AS rn
   FROM T_TicketPrint
)
SELECT cte1.*, oa.TicketBarCode
FROM cte1
OUTER APPLY (
   SELECT * FROM cte2
   WHERE cte1.ActionTicketID = cte2.ActionTicketID AND cte1.TicketOrderID = cte2.OrderTicketID AND cte1.rn = cte2.rn
) oa
order by dbo.func_ConvertToInt(cte1.SeatNumber), cte1.ActionTicketID, cte1.Created

当我尝试保存它时,会出现此错误:" ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效,除非TOP,OFFSET或FOR XML也是。指定"

查询有什么问题?

2 个答案:

答案 0 :(得分:1)

视图中的

ORDER BY子句本身并没有意义。视图中的行不会以相同的方式排序,因为表格中的行没有任何顺序。

因此,您可以完全删除视图中的ORDER BY子句,也可以保留ORDER BY并将TOP (100) PERCENT添加到SELECT子句中。通常,拥有TOP (100) PERCENTORDER BY没有意义,因为它只会减慢查询速度。当ORDER BY以某种方式限制行数时,视图中的TOP是有意义的。

我想说清楚。这是一种常见的误解。如果将视图定义为:

CREATE VIEW SomeView
AS
SELECT TOP(100) PERCENT SomeColumn
FROM SomeTable
ORDER BY SomeColumn

然后SELECT来自该视图,而不是ORDER BY

SELECT SomeColumn
FROM SomeView

然后,由于此SELECT而返回的行的顺序未定义,可以是任何行。有时它可能由SomeColumn订购,有时不订购。这取决于很多事情。 只有当您向最终ORDER BY添加SELECT时,您才能获得有保证的订单:

SELECT SomeColumn
FROM SomeView
ORDER BY SomeColumn

答案 1 :(得分:0)

是的,您通常 在视图或子查询中没有order by。如果您确实需要有序输出,请尝试使用SELECT TOP 100 PERCENT黑客。

将其放入最后的select

.
.
.
SELECT TOP 100 PERCENT cte1.*, oa.TicketBarCode
FROM cte1
OUTER APPLY (
   SELECT * FROM cte2
   WHERE cte1.ActionTicketID = cte2.ActionTicketID AND cte1.TicketOrderID = cte2.OrderTicketID AND cte1.rn = cte2.rn
) oa
order by dbo.func_ConvertToInt(cte1.SeatNumber), cte1.ActionTicketID, cte1.Created