2013-06-03 34 views
0

我正在将Oracle查询移植到Oracle。插入...用Oracle中的组选择结果太多值

INSERT INTO 
    "stagedInserts" ("systemId", "timestamp") 
SELECT 
    :systemId AS "systemId", "d"."time" AS "timestamp" 
FROM 
    "data" "d" 
WHERE 
    "d"."systemId" = :systemId 
GROUP BY 
    TRUNC("d"."time"/900) 

的GROUP BY旨在是的"time" DIV 900在MySQL等效,以确保我们最终只有一个为每个15分钟(900秒)间隔时间戳记。

查看上述查询结果为ORA-00979: not a GROUP BY expression

但是,如果我的组添加到SELECT,所以我们结束:

SELECT 
    :systemId AS "systemId", "d"."time" AS "timestamp", TRUNC("d"."time"/900) 

它导致:ORA-00913: too many values

我该如何解决这个问题?

+2

这是一个mySQL似乎被“破坏”给我们这些不使用它的人的例子!如果你的'data'表包含时间值为1,2,3,... 899的':systemId'的行,那么mySQL在'time/900'分组后将'storedInserts'中存储哪一个?无论答案是什么,它都是任意的。 –

回答

2

你可以在d.time使用聚合函数:

SELECT :systemId AS systemId, MAX(d.time) AS timestamp 
           ----------- 
FROM data d 
WHERE d.systemId = :systemId 
GROUP BY TRUNC(d.time/900); 

或者你可以这样做:

SELECT :systemId AS systemId, TRUNC(d.time/900)*900 AS timestamp 
           --------------------- 
FROM data d 
WHERE d.systemId = :systemId 
GROUP BY TRUNC(d.time/900); 

现在你选择的是在GROUP BY子句中使用的值,并乘以一个常数,而不是选择一个完全不同的值。

注意:这两个查询的结果是不一样的,所以考虑哪个更可取。

0

在第一种情况下,您会收到错误信息,因为无论何时将GROUP BY子句添加到您的查询中,您都应该在列名中包含相同的值,这在第一个查询中错过了。

在表再添加一个列Trunc_Column,这将您的类似查询的东西存储截断值,并切换到

INSERT INTO 
    "stagedInserts" ("systemId", "timestamp","Trunc_Column") 
SELECT 
    :systemId AS "systemId", "d"."time" AS "timestamp",TRUNC("d"."time"/900) 
FROM 
    "data" "d" 
WHERE 
    "d"."systemId" = :systemId 
GROUP BY 
    TRUNC("d"."time"/900) 

上面的语句将解决ORA-00913: too many values错误。