在SQL查询中声明,设置和使用变量(不是存储过程)

时间:2015-12-31 14:52:00

标签: sql sql-server

也许我错过了一些简单的东西,但有没有办法声明一个变量并在单个SQL查询中使用它?这样,如果您有一条使用大型嵌套查询生成的信息,则不必一遍又一遍地继续运行相同的查询。

这将是一个很好的例子来说明问题:

SELECT id, CASE WHEN LEN(HUGESUBQUERY) > 10 THEN
    LEFT(HUGESUBQUERY, LEN(HUGESUBQUERY)-2) ELSE HUGESUBQUERY END AS result FROM table

随着所有内容的加入,它变得非常长。这是我正在使用的实际查询。 (值得注意的是,我是从Dynamics AX运行的,因此除了一个SELECT语句中的所有内容之外,我没有其他任何操作的灵活性。在此环境中,没有任何DECLARE,SET等解决方案可用。)

SELECT (CAST (
CASE WHEN
RIGHT(
(CONCAT(COALESCE((SELECT TOP 1 SalesId FROM CustInvoiceJour WHERE     
CustInvoiceJour.InvoiceId = T1.INVOICE), 'NONE'), 
'-', ROW_NUMBER () OVER (PARTITION BY T1.ACCOUNTNUM, (SELECT TOP 1 SalesId     
FROM CustInvoiceJour 
WHERE CustInvoiceJour.InvoiceId = T1.INVOICE) ORDER BY T1.DUEDATE)-1))
, 2) = '-0'
THEN
LEFT(
(CONCAT(COALESCE((SELECT TOP 1 SalesId FROM CustInvoiceJour WHERE     
CustInvoiceJour.InvoiceId = T1.INVOICE), 'NONE'), 
'-', ROW_NUMBER () OVER (PARTITION BY T1.ACCOUNTNUM, (SELECT TOP 1 SalesId     
FROM CustInvoiceJour 
WHERE CustInvoiceJour.InvoiceId = T1.INVOICE) ORDER BY T1.DUEDATE)-1)),
LEN(
(CONCAT(COALESCE((SELECT TOP 1 SalesId FROM CustInvoiceJour WHERE     
CustInvoiceJour.InvoiceId = T1.INVOICE), 'NONE'), 
'-', ROW_NUMBER () OVER (PARTITION BY T1.ACCOUNTNUM, (SELECT TOP 1 SalesId     
FROM CustInvoiceJour 
WHERE CustInvoiceJour.InvoiceId = T1.INVOICE) ORDER BY T1.DUEDATE)-1))
)-2
)
ELSE
(CONCAT(COALESCE((SELECT TOP 1 SalesId FROM CustInvoiceJour WHERE 
CustInvoiceJour.InvoiceId = T1.INVOICE), 'NONE'), 
'-', ROW_NUMBER () OVER (PARTITION BY T1.ACCOUNTNUM, (SELECT TOP 1 SalesId     
FROM CustInvoiceJour 
WHERE CustInvoiceJour.InvoiceId = T1.INVOICE) ORDER BY T1.DUEDATE)-1))
END
AS NVARCHAR(21))) AS DOC_ID,
T1.ACCOUNTNUM AS CUSTOMER_ID,T1.AMOUNTCUR AS DOCTOTAL,T1.DUEDATE AS 
DUEDATE,T1.DOCUMENTDATE AS DOCDATE,
T1.RECID AS ID,T1.DATAAREAID AS DATAAREAID,T1.PARTITION AS 
PARTITION,T1.RECID AS RECID,
(CAST ((T1.RECID + T1.RECVERSION) AS BIGINT)) AS SWX_COMPUTEDVERSION FROM     
CUSTTRANS T1 WHERE (AMOUNTCUR>0)
ORDER BY DOC_ID

2 个答案:

答案 0 :(得分:1)

是的,您可以认为query不是相关。试试这个

DECLARE @HUGESUBQUERY VARCHAR(500) 

SET @HUGESUBQUERY = (SELECT TOP 1 something 
                     FROM   somewhere 
                            INNER JOIN table2 
                                    ON table2.id = somwhere.id 
                            INNER JOIN table3 
                                    ON table3.id = table2.id 
                     WHERE  condition1 = condition1 
                            AND condition2 = condition2) 

SELECT id, 
       CASE @HUGESUBQUERY 
         WHEN Len(@HUGESUBQUERY) > 10 THEN LEFT(@HUGESUBQUERY, 
                                           Len(@HUGESUBQUERY) - 2) 
       END AS result 
FROM   table 

答案 1 :(得分:1)

对于相关子查询,您可以使用CROSS APPLY。由于我们没有真正的查询,我只会放一个演示该技术的文章:

select
    *,cname
from
    sys.objects so
        cross apply
    (select top 1 sc.name from sys.columns sc where sc.object_id = so.object_id) t (cname)

现在可以在cname子句中使用SELECT来引用name返回的sys.columns值。