2011-01-26 55 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)