Tsql 如何在计算其他字段时使用别名

Tsql 如何在计算其他字段时使用别名,tsql,subquery,Tsql,Subquery,有人知道有没有方法可以复制在t-SQL中使用子查询的别名对另一个字段执行计算时使用的方法 我尝试在MS SQL Express中对以下查询使用相同的语法,但出现以下错误: DECLARE @PracticeID INT DECLARE @Date1 date DECLARE @Date2 date SET @PracticeID = 11015 SET @Date1 = '2017-06-01' SET @Date2 = '2017-09-01' SELECT prtc.PracticeNa

有人知道有没有方法可以复制在t-SQL中使用子查询的别名对另一个字段执行计算时使用的方法

我尝试在MS SQL Express中对以下查询使用相同的语法,但出现以下错误:

DECLARE @PracticeID INT
DECLARE @Date1 date
DECLARE @Date2 date

SET @PracticeID = 11015
SET @Date1 = '2017-06-01'
SET @Date2 = '2017-09-01'

SELECT prtc.PracticeName ,COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,  
           COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
          ( SELECT COUNT(*)
            FROM UserEvent UE
            WHERE UE.EventTypeID = 1 AND
                  UE.PracticeID = au.PracticeID AND
                  (UE.EventDate BETWEEN @Date1 and @Date2)
          ) TotalNumberLogins, 
          (SELECT TotalNumberofLogins) - ((SELECT iOSLogins) + (SELECT AndroidLogins )) DesktopLogins
    FROM UserDeviceInfo UDI JOIN
         AppUser AU ON udi.UserID = au.UserID JOIN
         Practice PRTC ON au.PracticeID = prtc.PracticeID 
    WHERE au.PracticeID = @PracticeID AND 
          (udi.Created BETWEEN @Date1 AND @Date2)
    GROUP BY prtc.PracticeName, au.PracticeID
Msg 207,级别16,状态1,第17行无效列名 “TotalNumberofLogins”。消息207,16级,状态1,第17行无效 列名“iOSLogins”。消息207,16级,状态1,第17行无效 列名“AndroidLogins”

这并不是说这会有什么不同,但我确实尝试过将别名放在引号和括号中,但没有用

通过使用与变量相同的值(而不是alias的值)执行计算,然后将它们插入表中,我确实从另一种方法中获得了所需的结果

但是,该查询非常冗长,我想知道是否有任何方法可以复制引用问题中的行为以供将来使用


感谢您提供的任何帮助。

该方法在SQL Server中不起作用。您可以通过两种不同的方式完成相同的任务:

1.)对每个别名列使用代码,而不是别名:

(SELECT COUNT(*)
 FROM UserEvent UE
 WHERE UE.EventTypeID = 1 
 AND UE.PracticeID = au.PracticeID 
 AND (UE.EventDate BETWEEN @Date1 and @Date2) 
- COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END)
+ COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) Desktop Logics
2.)使用派生表生成列,然后可以通过别名引用它们:

SELECT PracticeName, iOSLogins, AndroidLogins, TotalNumberLogins,
       (TotalNumberofLogins - (iOSLogins + AndroidLogins)) DesktopLogins
FROM (
       SELECT prtc.PracticeName,
              COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,  
              COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
             ( SELECT COUNT(*)
               FROM UserEvent UE
               WHERE UE.EventTypeID = 1 
               AND UE.PracticeID = au.PracticeID 
               AND (UE.EventDate BETWEEN @Date1 and @Date2)
             ) TotalNumberLogins, 
       FROM UserDeviceInfo UDI 
       JOIN AppUser AU ON udi.UserID = au.UserID 
       JOIN Practice PRTC ON au.PracticeID = prtc.PracticeID 
       WHERE au.PracticeID = @PracticeID 
       AND (udi.Created BETWEEN @Date1 AND @Date2)
       GROUP BY prtc.PracticeName, au.PracticeID
    ) a --table alias
编辑:已解释的表格别名

在一个简单的查询中:

SELECT col1 FROM Table
您知道
col1
的表引用是
table
。(
Table.Col1
)如果它是唯一的
Col1
,则不必编写它,但您仍然知道它所引用的表

在简单的派生表中:

SELECT col1 FROM (SELECT col1 FROM Table)
内部列的表引用仍然是
table
,但是外部列呢?在本例中,括号内的所有内容都是表,但在上面的示例中,该表未命名。SQL Server要求您命名/别名已创建的表,以便可以引用它:

SELECT col1 FROM (SELECT col1 FROM Table) MyDerivedTable
…现在,您的外部列有一个表引用:

SELECT MyDerivedTable.col1 FROM (SELECT col1 FROM Table) MyDerivedTable
一旦涉及到更多的表,您还可以看到对此的更大需求:

SELECT MyDerivedTable.col1
FROM (SELECT col1 FROM Table) MyDerivedTable
JOIN Table T on T.col1 = MyDerivedTable.col1
编辑2:CTE选项:

另一个选项是公共表表达式或CTE:

with cteName as (
SELECT prtc.PracticeName,
       COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,  
       COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
         ( SELECT COUNT(*)
           FROM UserEvent UE
           WHERE UE.EventTypeID = 1 
           AND UE.PracticeID = au.PracticeID 
           AND (UE.EventDate BETWEEN @Date1 and @Date2)
         ) TotalNumberLogins, 
   FROM UserDeviceInfo UDI 
   JOIN AppUser AU ON udi.UserID = au.UserID 
   JOIN Practice PRTC ON au.PracticeID = prtc.PracticeID 
   WHERE au.PracticeID = @PracticeID 
   AND (udi.Created BETWEEN @Date1 AND @Date2)
   GROUP BY prtc.PracticeName, au.PracticeID
)

SELECT PracticeName, iOSLogins, AndroidLogins, TotalNumberLogins,
       (TotalNumberofLogins - (iOSLogins + AndroidLogins)) DesktopLogins
FROM cteName

这些查询非常方便,因为它们在外部查询和内部查询之间创建了清晰的分隔。最终,它与内联派生表的功能相同,因此请选择对您来说更可读的版本。(xorcus建议添加CTE的道具)

您的第二个建议正是我想要的答案类型。非常感谢亚伦,你帮了我很大的忙。顺便提一下,如果我删除了“a”表别名,为什么查询会失败?@W.Harr很乐意提供帮助。我在回答中添加了一个别名的解释,因为它太长了,不能作为评论来写。简单的回答是,您正在从结果集创建一个伪表,SQL Server要求您命名表以便引用。您可能会发现使用比嵌套查询更可读:@xorcus Good call,我在中也添加了该选项:)