Sql Oracle中的三列Group By?

Sql Oracle中的三列Group By?,sql,oracle,Sql,Oracle,我有两个不同的结果集: Result 1: +--------------+--------------+ | YEAR_MONTH | UNIQUE_USERS | +--------------+--------------+ | 2013-08 | 1111 | +--------------+--------------+ | 2013-09 | 2222 | +--------------+--------------+ Re

我有两个不同的结果集:

Result 1:

+--------------+--------------+
| YEAR_MONTH   | UNIQUE_USERS |
+--------------+--------------+
|   2013-08    |     1111     |
+--------------+--------------+
|   2013-09    |     2222     |
+--------------+--------------+

Result 2:

+--------------+----------------+
| YEAR_MONTH   | UNIQUE_ACTIONS |
+--------------+----------------+
|   2013-08    |   111111111    |
+--------------+----------------+
|   2013-09    |   222222222    |
+--------------+----------------+
结果1的代码

SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH, COUNT(DISTINCT EMPLOYEE_ID) UNIQUE_USERS
    FROM CORE.DATE_TEST
GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
ORDER BY YEAR_MONTH ASC
SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH, COUNT(DISTINCT EMPLOYEE_ACTION) UNIQUE_ACTIONS
    FROM CORE.ACTION_TEST
GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
ORDER BY YEAR_MONTH ASC
结果2的代码

SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH, COUNT(DISTINCT EMPLOYEE_ID) UNIQUE_USERS
    FROM CORE.DATE_TEST
GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
ORDER BY YEAR_MONTH ASC
SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH, COUNT(DISTINCT EMPLOYEE_ACTION) UNIQUE_ACTIONS
    FROM CORE.ACTION_TEST
GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
ORDER BY YEAR_MONTH ASC
但是,我尝试通过简单的操作将它们分组:

SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH, COUNT(DISTINCT EMPLOYEE_ID) UNIQUE_USERS, COUNT(DISTINCT EMPLOYEE_ACTION) UNIQUE_ACTIONS
    FROM CORE.DATE_TEST, CORE.ACTION_TEST
GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
ORDER BY YEAR_MONTH ASC
这是行不通的。我还在第二个结果集(
result set 1
had
t1
作为变量名,
result set 2
had
t2
)上尝试了一个
内部联接,并在t2上得到了错误,
无效标识符

这是我想要的输出:

+--------------+--------------+----------------+
| YEAR_MONTH   | UNIQUE_USERS | UNIQUE_ACTIONS |
+--------------+--------------+----------------+
|   2013-08    |     1111     |    111111111   |   
+--------------+--------------+----------------+
|   2013-09    |     2222     |    222222222   |
+--------------+--------------+----------------+

我如何正确地做到这一点?它不一定需要是一个三列的groupby;它只需要工作。

如果两个表都有许多记录,笛卡尔连接是一个糟糕的解决方案,可能实际上无法提供您想要的答案。我会这样解决这个问题:

SELECT   TO_CHAR (COALESCE (t1.year_month, t2.year_month), 'yyyy-mm')
            AS year_month,
         t1.unique_users,
         t2.unique_actions
FROM     (SELECT   TRUNC (access_date, 'mm') AS year_month,
                   COUNT (DISTINCT employee_id) AS unique_users
          FROM     core.date_test
          GROUP BY TRUNC (access_date, 'mm')) t1
         FULL OUTER JOIN
         (SELECT   TRUNC (access_date, 'mm') AS year_month,
                   COUNT (DISTINCT employee_action) AS unique_actions
          FROM     core.action_test
          GROUP BY TRUNC (access_date, 'mm')) t2
            ON t1.year_month = t2.year_month
ORDER BY COALESCE (t1.year_month, t2.year_month) ASC

笛卡尔联接性能不佳的原因是,在应用
group by
之前,第一个表中的每一行都必须与第二个表中的每一行匹配。如果每个表只有1000行,那么数据库必须构造1000000个值。

如果两个表都有许多记录,笛卡尔连接是一个糟糕的解决方案,可能实际上无法提供您想要的答案。我会这样解决这个问题:

SELECT   TO_CHAR (COALESCE (t1.year_month, t2.year_month), 'yyyy-mm')
            AS year_month,
         t1.unique_users,
         t2.unique_actions
FROM     (SELECT   TRUNC (access_date, 'mm') AS year_month,
                   COUNT (DISTINCT employee_id) AS unique_users
          FROM     core.date_test
          GROUP BY TRUNC (access_date, 'mm')) t1
         FULL OUTER JOIN
         (SELECT   TRUNC (access_date, 'mm') AS year_month,
                   COUNT (DISTINCT employee_action) AS unique_actions
          FROM     core.action_test
          GROUP BY TRUNC (access_date, 'mm')) t2
            ON t1.year_month = t2.year_month
ORDER BY COALESCE (t1.year_month, t2.year_month) ASC
笛卡尔联接性能不佳的原因是,在应用
group by
之前,第一个表中的每一行都必须与第二个表中的每一行匹配。如果每个表只有1000行,则数据库必须构造1000000个值。

尝试:

select a.YEAR_MONTH, a.UNIQUE_USERS, b.UNIQUE_ACTIONS
from (
    SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH,
        COUNT(DISTINCT EMPLOYEE_ID) UNIQUE_USERS
    FROM CORE.DATE_TEST
    GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
) a
join (
    SELECT TO_CHAR(ACCESS_DATE, 'yyyy-mm') YEAR_MONTH,
        COUNT(DISTINCT EMPLOYEE_ACTION) UNIQUE_ACTIONS
    FROM CORE.ACTION_TEST
    GROUP BY TO_CHAR(ACCESS_DATE, 'yyyy-mm')
) b
on a.YEAR_MONTH = b.YEAR_MONTH
order by a.YEAR_MONTH ASC
尝试:

希望这能起作用,因为我们需要指定要从中提取行的表名


希望这能起作用,因为我们需要指定要从中提取行的表名。…

完全外部连接两个SELECT,包括PLSQL中的GROUP BY?我以为只有SQL:1999语法才支持
完全外部联接
?对不起,我不知道这个限制。这不是PL/SQL。是的,因为您的问题中没有任何PL/SQL。它们是纯SQL。PL/SQL仅用于存储过程/函数或触发器。因此,除非您对存储过程(或匿名PL/SQL块)有问题,
plsql
标记不正确。在plsql中,将两个SELECT包括GROUP BY?我以为只有SQL:1999语法才支持
完全外部联接
?对不起,我不知道这个限制。这不是PL/SQL。是的,因为您的问题中没有任何PL/SQL。它们是纯SQL。PL/SQL仅用于存储过程/函数或触发器。因此,除非您对存储过程(或匿名PL/SQL块)有问题,
plsql
标记是不正确的!这比下面的解决方案快一百万倍。我不知道你可以用这种方式做选择。是时候练习了!如果一个年/月组合出现在一个表中,但不出现在另一个表中,则该年/月将从结果中忽略。太好了!这比下面的解决方案快一百万倍。我不知道你可以用这种方式做选择。是时候练习了!如果一个年/月组合出现在一个表中,但不出现在另一个表中,则该年/月将从结果中忽略。