Oracle:表上的聚合计数

时间:2016-07-07 00:26:36

标签: sql oracle

我在尝试获得整体计数方面遇到了困难,并且将每个状态都计入了一个平台。

为了帮助理解表结构,下面是我正在使用的2个表的示例。

英雄:

Pin             Name                 Status
1               Batman               Fighting Crime
1               Superman             Fighting Crime
1               Daredevil            Eating Food
2               Spiderman            Watching TV         
3               Wolverine            Eating Food
4               Cyclops              Watching TV
4               Jean Gray            Watching TV
4               Prof X               Eating Food

然后是另一张表,地点:

Loc_Pin         Place     
1               Gotham City
2               Cloud City
3               New York City
4               Washington DC
5               My House

使用这两个表,我希望得到一个看起来像这样的预期输出:

LOCATION          Number of Heroes       Number Fighting         Number Eating          Number Watching TV
Gotham City       3                      2                       1                      0
Cloud City        1                      0                       0                      1
New York City     1                      0                       1                      0
Washington DC     3                      0                       1                      2
My House          0                      0                       0                      0

我觉得我几乎就在那里。我首先将我的选择语句排成一行,以便将状态和英雄的总计数计入各自的位置。我的主要问题是我需要在表中表示0而不是空值。所以在我的更新声明中,我试图指出自己,我认为这是我遇到的问题。

这是我到目前为止的SQL查询示例。我只是想填补"打击犯罪"现在做一些概念证明,我可以通过扩展案例陈述来考虑其他状态:

MERGE
INTO Counts finalCount
USING (
    SELECT DISTINCT
        myCounts.PIN
        ,myCounts.status
        ,holder.status
        ,holder.status_count
    FROM
        Counts myCounts
        , (select   count(heroes.status) status_count,
                            heroes.status status,
                            loc.loc_pin loc_pin

                    from     heroes_permit_mv heroes,
                            Location loc

                    where    heroes.pin = loc.pin
                    group by heroes.status, loc.loc_pin) holder
    WHERE   myCounts.pin = holder.pin
) updateMe
ON (finalCount.PIN = updateMe.PIN)
WHEN MATCHED THEN
UPDATE
    SET finalCount.status = CASE WHEN TRIM(updateMe.status) = 'Fighting Crime' THEN updateMe.status_count ELSE 0 END

但是我遇到[错误]执行(2:6):ORA-30926:无法在源表中获得一组稳定的行

我已经尝试查找此错误,最常见的答案是在我的SQL查询中添加DISTINCT语句,我做了但仍然似乎没有帮助。当我在update语句之外逐个选择我的查询时,它会全部解析并按预期运行。就在我做最后更新声明时,我从Oracle那里得到了这个错误。

我还尝试使用UPDATE语句对此进行攻击,但我收到另一个错误说[错误]执行(21:8):ORA-01779:无法修改映射到非密钥保留的列表

在这一点上的任何提示都会非常感激,因为在过去的几天里我一直在反对这一点。

2 个答案:

答案 0 :(得分:2)

您可以使用带有条件聚合的数据透视查询:

SELECT t1.Place AS LOCATION,
       COUNT(*) AS Number_Of_Heroes,
       SUM(CASE WHEN COALESCE(t2.Status, '') = 'Fighting Crime'
                THEN 1 ELSE 0 END) AS Number_Fighting,
       SUM(CASE WHEN COALESCE(t2.Status, '') = 'Eating Food' 
                THEN 1 ELSE 0 END) AS Number_Eating,
       SUM(CASE WHEN COALESCE(t2.Status,'') = 'Watching TV' 
                THEN 1 ELSE 0 END) AS Number_Watching_TV
FROM Locations t1 INNER JOIN Heroes t2
    ON t1.Loc_Pin = t2.Pin
GROUP BY t1.Place

答案 1 :(得分:1)

使用Oracle 11 pivot语法的pivot查询:

select * from (
    select pin, count(*) over (partition by pin) Number_of_Heroes, name, status
    from heroes
              )
pivot (count(name) for status in ('Fighting Crime', 'Eating Food', 'Watching TV'));

您可以使用Locations表对结果进行外连接以获得最终结果。

输出:

       PIN NUMBER_OF_HEROES 'Fighting Crime' 'Eating Food' 'Watching TV'
---------- ---------------- ---------------- ------------- -------------
         2                1                0             0             1
         1                3                2             1             0
         3                1                0             1             0
         4                3                0             1             2