带有(来自)别名的 SQL 子查询

Posted

技术标签:

【中文标题】带有(来自)别名的 SQL 子查询【英文标题】:SQL subquery with (from) aliases 【发布时间】:2015-08-25 17:40:20 【问题描述】:

我需要关于 select 子句中的子查询的帮助。我有表:EMPLOYEES (EMPLOYEE_ID, EMPLOYEE_NAME, EMPLOYEE_GROUP) 和 ACTIVITIES (ACTIVITY_DATE, ACTIVITY_STATUS, EMPLOYEE_ID)。我需要为“W”组的员工选择一些活动。

很遗憾,我不能使用 CREATE TABLE/VIEW 功能,所以我尝试了这个,但它不起作用。

SELECT DISTINCT

TB1.EMPLOYEE_NAME,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'START' AND TB1.ACTIVITY_NUMBER = 1) AS FIRST_START,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'START' AND TB1.ACTIVITY_NUMBER = 2) AS SECOND_START,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'STOP' AND TB1.ACTIVITY_NUMBER = 1) AS FIRST_STOP,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'STOP' AND TB1.ACTIVITY_NUMBER = 2) AS SECOND_STOP

FROM( 

     SELECT DISTINCT

     A.EMPLOYEE_NAME,        
     B.ACTIVITY_DATE,
     B.ACTIVITY_STATUS,
     ROW_NUMBER() OVER (PARTITION BY A.EMPLOYEE_NAME,B.ACTIVITY_STATUS 
       ORDER BY B.ACTIVITY_DATE ASC) ACTIVITY_NUMBER

     FROM 
     (SELECT * FROM EMPLOYEES WHERE EMPLOYEE_GROUP ='W')  A

     LEFT JOIN ( SELECT * FROM ACTIVITIES  WHERE ACTIVITY_STATUS IN ('START','STOP','PAUSE') )B
      ON A.EMPLOYEE_ID = B.EMPLOYEE_ID

  ) TB1

你知道任何函数,我可以用它从带有别名的表中选择数据吗?

【问题讨论】:

你试过CTE(公用表表达式)吗?? 公用表表达式在 Oracle 文档中称为子查询因式分解。至少这是我最后一次阅读 Oracle 文档。 【参考方案1】:

我不确定您的 Oracle 版本是否支持它,但您要么必须将 TB1 定义为 CTE(公用表表达式):

WITH TB1 AS ( 

     SELECT DISTINCT

     A.EMPLOYEE_NAME,        
     B.ACTIVITY_DATE,
     B.ACTIVITY_STATUS,
     ROW_NUMBER() OVER (PARTITION BY A.EMPLOYEE_NAME,B.ACTIVITY_STATUS 
       ORDER BY B.ACTIVITY_DATE ASC) ACTIVITY_NUMBER

     FROM 
     (SELECT * FROM EMPLOYEES WHERE EMPLOYEE_GROUP ='W')  A

     LEFT JOIN ( SELECT * FROM ACTIVITIES  WHERE ACTIVITY_STATUS IN ('START','STOP','PAUSE') )B
      ON A.EMPLOYEE_ID = B.EMPLOYEE_ID

  )
SELECT DISTINCT

TB1.EMPLOYEE_NAME,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'START' AND TB1.ACTIVITY_NUMBER = 1) AS FIRST_START,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'START' AND TB1.ACTIVITY_NUMBER = 2) AS SECOND_START,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'STOP' AND TB1.ACTIVITY_NUMBER = 1) AS FIRST_STOP,
(SELECT TB1.ACTIVITY_DATE FROM TB1 
WHERE TB1.ACTIVITY_STATUS = 'STOP' AND TB1.ACTIVITY_NUMBER = 2) AS SECOND_STOP

FROM TB1

或者,老式的方法是复制粘贴每个“TB1”实例的定义。 (是的,真的,这就是我们过去的做法。)

【讨论】:

以上是关于带有(来自)别名的 SQL 子查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL 从带有子查询的多个表中选择数据(包括来自内部连接的数据)错误:1242

SQL LEFT JOIN 子查询别名

SQL Server - 在子查询中使用列别名

sql查询语句学习,多表查询和子查询以及连接查询

PL/SQL 在插入语句的子查询中使用别名和函数

SQL高级语句(包含子查询,连接查询,视图联集等)