Sql ORDER BY中的查询是否会被重复计算?

Sql ORDER BY中的查询是否会被重复计算?,sql,tsql,Sql,Tsql,我有几个数据库对象需要从表中提取单个记录(如TOP 1),但选择哪个记录的优先级取决于设置表中的位值,并且该设置表将只包含一行 我已经编写了一个视图,它将执行所需的功能: CREATE VIEW TopOrganisationAddresses AS WITH cte AS ( SELECT OrganisationID, AddressID, CASE WHEN EXISTS (SELECT * FROM GlobalSettings

我有几个数据库对象需要从表中提取单个记录(如TOP 1),但选择哪个记录的优先级取决于设置表中的位值,并且该设置表将只包含一行

我已经编写了一个视图,它将执行所需的功能:

CREATE VIEW TopOrganisationAddresses AS
WITH cte AS
(
    SELECT  OrganisationID,
            AddressID,
            CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports=1) THEN IsDeliveryAddress ELSE IsInvoiceAddress END AS OrderFirst,
            CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports=1) THEN IsInvoiceAddress ELSE IsDeliveryAddress END AS OrderSecond
    FROM OrganisationAddresses
)

SELECT OrganisationID, AddressID,
        ROW_NUMBER() OVER(PARTITION BY OrganisationID
                            ORDER BY OrderFirst DESC, OrderSecond DESC) AS [Row]
FROM cte

是否会对OrganizationAddresses表中的每个fow计算SELECT*FROM GlobalSettings查询?如果是这样,这将是非常浪费的,因为它只是一个不会改变的静态值。

理论上可以对其进行优化,但您可能只需要使用另一个
cte
即可
选择
以保证它,例如

CREATE VIEW TopOrganisationAddresses AS
WITH cteg AS 
(
    SELECT CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports=1) THEN 1 ELSE 0 END AS dair
),
cte AS
(
    SELECT  OrganisationID,
            AddressID,
            CASE WHEN cteg.dair = 1 THEN IsDeliveryAddress ELSE IsInvoiceAddress END AS OrderFirst,
            CASE WHEN cteg.dair = 1 THEN IsInvoiceAddress ELSE IsDeliveryAddress END AS OrderSecond
    FROM OrganisationAddresses
    CROSS JOIN cteg
)

SELECT OrganisationID, AddressID,
        ROW_NUMBER() OVER(PARTITION BY OrganisationID
                            ORDER BY OrderFirst DESC, OrderSecond DESC) AS [Row]
FROM cte

理论上,它可以被优化掉,但是你可以使用另一个
cte
,它可以
SELECT
来保证它

CREATE VIEW TopOrganisationAddresses AS
WITH cteg AS 
(
    SELECT CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports=1) THEN 1 ELSE 0 END AS dair
),
cte AS
(
    SELECT  OrganisationID,
            AddressID,
            CASE WHEN cteg.dair = 1 THEN IsDeliveryAddress ELSE IsInvoiceAddress END AS OrderFirst,
            CASE WHEN cteg.dair = 1 THEN IsInvoiceAddress ELSE IsDeliveryAddress END AS OrderSecond
    FROM OrganisationAddresses
    CROSS JOIN cteg
)

SELECT OrganisationID, AddressID,
        ROW_NUMBER() OVER(PARTITION BY OrganisationID
                            ORDER BY OrderFirst DESC, OrderSecond DESC) AS [Row]
FROM cte

SQL Server应该足够智能,可以只运行一次查询。优化器应该准确地识别您所做的事情——这些都是常量值。例如,以下查询为
id
返回相同的值:

with cte as (
      select v.*,
             (select top 1 newid() from (values (1), (2)) v2(n) order by newid()) as val
      from (values (1), (2)) v(n)
     )
select *
from cte;
(是一把小提琴。)

如果要确保这些值只计算一次,可以将逻辑移到
FROM
子句:

CREATE VIEW TopOrganisationAddresses AS
    SELECT oa.OrganisationID, oa.AddressID,
            ROW_NUMBER() OVER (PARTITION BY oa.OrganisationID
                               ORDER BY v.OrderFirst DESC, v.OrderSecond DESC
                              ) AS [Row]
    FROM OrganisationAddresses oa CROSS JOIN
         (VALUES (CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports = 1) THEN IsDeliveryAddress ELSE IsInvoiceAddress END,,
                  CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports = 1) THEN IsInvoiceAddress ELSE IsDeliveryAddress END)
         ) v(OrderFirst, OrderSecond);

SQL Server应该足够智能,可以只运行一次查询。优化器应该准确地识别您所做的事情——这些都是常量值。例如,以下查询为
id
返回相同的值:

with cte as (
      select v.*,
             (select top 1 newid() from (values (1), (2)) v2(n) order by newid()) as val
      from (values (1), (2)) v(n)
     )
select *
from cte;
(是一把小提琴。)

如果要确保这些值只计算一次,可以将逻辑移到
FROM
子句:

CREATE VIEW TopOrganisationAddresses AS
    SELECT oa.OrganisationID, oa.AddressID,
            ROW_NUMBER() OVER (PARTITION BY oa.OrganisationID
                               ORDER BY v.OrderFirst DESC, v.OrderSecond DESC
                              ) AS [Row]
    FROM OrganisationAddresses oa CROSS JOIN
         (VALUES (CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports = 1) THEN IsDeliveryAddress ELSE IsInvoiceAddress END,,
                  CASE WHEN EXISTS (SELECT * FROM GlobalSettings WHERE DeliveryAddressInReports = 1) THEN IsInvoiceAddress ELSE IsDeliveryAddress END)
         ) v(OrderFirst, OrderSecond);

这两个子查询是相同的,您的意思是在其中一个子查询中写入不同的WHERE条件吗?这两个子查询是相同的,您的意思是在其中一个子查询中写入不同的WHERE条件吗?