2011-01-26 60 views
3

該查詢按原樣執行。但是,SQL Management Studio不會將其保存爲視圖,因爲我定義了一個變量。查看,存儲過程或表定義的函數

 
DECLARE @HighestTransaction int 

SET @HighestTransaction = (SELECT  MAX(CardID) 
          FROM   dbo.Transactions) 

SELECT Uploads.*, Transactions.* 
FROM Uploads LEFT OUTER JOIN 
     dbo.Transactions ON dbo.Uploads.Code = dbo.Transactions.CardID 
WHERE (Uploads.Code > CASE WHEN 
      @HighestTransaction IS NULL THEN -1 ELSE @HighestTransaction END) 

我還沒有真正發揮各地使用存儲過程,或用戶定義的函數一大堆,所以我不知道的去這樣做的最佳方式。或者,如果有更好的方法來寫這篇文章,我也會接受建議。

+0

,並指定你在需要的領域選擇。選擇*是一種特別差的編碼習慣,因爲你有一個加入,你會返回一個字段兩次,這是浪費資源。 – HLGEM 2011-01-26 20:39:00

+0

如果其中一個表的列數很少,那麼SELECT *會出現問題,另一個是非常具體的視圖,並且所有結果列將由調用方使用?無論如何,我寫了SELECT *來節省空間,而不是分散其他東西。真正的查詢確實展開了所有的列,因爲這是VS和SQL Management Studio在安裝SELECT *時自動執行的操作。 – kettch 2011-01-26 22:56:43

回答

5
  • 您可以在MAX隔離成CTE
  • MAX沒有GROUP BY給一個行,讓你用ISNULL有

喜歡的東西...

WITh cHighestCard AS 
(
    SELECT ISNULL(MAX(CardID), -1) AS MaxCard FROM dbo.Transactions 
) 
SELECT  STAUpload.*, Transactions.* 
FROM   dbo.STAUpload LEFT OUTER JOIN 
         dbo.Transactions ON dbo.STAUpload.Code = dbo.Transactions.CardID 
WHERE  dbo.STAUpload.Code > MaxCard --edit, error spotted by martin 

編輯:不需要CTE:它混合了集合和標量。哎呀。

SELECT  STAUpload.*, Transactions.* 
FROM   dbo.STAUpload LEFT OUTER JOIN 
         dbo.Transactions ON dbo.STAUpload.Code = dbo.Transactions.CardID 
WHERE  dbo.STAUpload.Code > 
      (SELECT ISNULL(MAX(CardID), -1) AS MaxCard 
        FROM dbo.Transactions) 
0

您可以重新編寫它作爲一個子查詢W /聚結以避免重複鍵入它:

SELECT .... 
    FROM .... 
WHERE dbo.STAUpload.code > COALESCE( 
     (Select max(cardId) from dbo.transactions),-1) 

然後它變成一個視圖。

+0

這仍然會執行兩次。 (http://connect.microsoft。com/SQLServer/feedback/details/336002 /不必要的性能不佳 - 合併子查詢) – 2011-01-26 20:22:43

+0

@Martin,@Ken Downs:那麼我會考慮ISNULL。如果cardID是smallint,那麼說。然後.code可能由於COALESCE數據類型處理而轉換爲int(優化器可能將-1視爲smallint,儘管如此) – gbn 2011-01-26 20:30:32

0

您可以在存儲過程中執行此操作。只需傳入您的變量,它將按需要工作。

在msdn或在線書籍上快速搜索和查看存儲過程。

2

既然你提到你試圖創建這個視圖,這意味着你可能想在另一個查詢中使用結果。如果那是真的,我會做這個table-valued function

0

這可能只是一個簡單的視圖,沒有使用CTE的作品。在子查詢中針對SELECT MAX的ISNULL可能更容易解釋將ISNULL內聯到子查詢中。

CREATE VIEW Q_SO 
AS 
SELECT Uploads.*, Transactions.* 
FROM Uploads 
LEFT OUTER JOIN dbo.Transactions 
    ON dbo.Uploads.Code = dbo.Transactions.CardID 
WHERE (Uploads.Code > ISNULL((SELECT MAX(CardID) FROM dbo.Transactions),-1)) 

作爲參數的表值函數

CREATE FUNCTION Q_FN() RETURNS TABLE AS RETURN 
SELECT Uploads.*, Transactions.* 
FROM Uploads 
LEFT OUTER JOIN dbo.Transactions 
    ON dbo.Uploads.Code = dbo.Transactions.CardID 
WHERE (Uploads.Code > ISNULL((SELECT MAX(CardID) FROM dbo.Transactions),-1)) 
0

只是CROSS JOIN是初始化@HighestTansaction到主查詢的子查詢,像這樣:

SELECT Uploads.*, Transactions.* 
FROM Uploads LEFT OUTER JOIN 
     dbo.Transactions ON dbo.Uploads.Code = dbo.Transactions.CardID CROSS JOIN 
     (SELECT ISNULL(MAX(CardID),-1) FROM dbo.Transactions) m(HighestTransaction) 
WHERE (Uploads.Code > m.HighestTransaction)