Postgres要求GROUP BY我不想要

时间:2014-06-04 09:07:18

标签: php sql codeigniter postgresql

我有这个代码,我在PHP和Codeigniter中使用:

查询1

return $this->db->query("
    SELECT max(dateandtime) as dateandtime 
    FROM table.dat_access 
    WHERE cardcode = 'w123' 
    ")->row();

结果很好,所以我现在想要根据这个来回溯另一个列(snapshot)所以我认为我需要这样做:

查询2

return $this->db->query("
    SELECT snapshot, max(dateandtime) as dateandtime 
    FROM table.dat_access 
    WHERE cardcode = 'w123' 
    ")->row();

此时我收到此错误:

ERROR: column "dat_access.snapshot" must appear in the GROUP BY clause or be used in an aggregate function

但我现在不想把事情分组。我只需要检索同一查询的快照值。

我需要的是为snapshot获取最大dateandtime行和指定cardcode的行。

我试过这个:

SELECT snapshot, max(dateandtime) as dateandtime
    FROM table.dat_access
    WHERE cardcode = 'w123'
    GROUP BY dateandtime LIMIT 1

但它给了我错误:

Error Number: ERROR: column "dat_access.snapshot" must appear in the GROUP BY
clause or be used in an aggregate function.
LINE 1: SELECT snapshot, max(dateandtime) as dateandtime FROM table...^
SELECT snapshot, max(dateandtime) as dateandtime FROM table.dat_access
WHERE cardcode = 'w123' 

Filename: [...]card_model.php

Line Number: 82

注意: 当我检索第一个查询的字段dateandtime时,工作正常。

2 个答案:

答案 0 :(得分:1)

这为您提供了最大的"数据和时间"对于单个卡片代码。

select cardcode, max(dateandtime) as dateandtime 
from table.dat_access 
group by cardcode
having cardcode = 'w123';

加入即可获得"快照"。您需要加入两个列 - " cardcode" " dateandtime"。

select t1.cardcode, t1.dateandtime, t1.snapshot
from table.dat_access t1
inner join (select cardcode, max(dateandtime) as dateandtime 
            from table.dat_access 
            group by cardcode
            having cardcode = 'w123') t2
  on t1.cardcode = t2.cardcode
 and t1.dateandtime = t2.dateandtime;

如果您想保持Query1不被修改,您可以将Query2更改为此。

return $this->db->query("
    SELECT cardcode, snapshot, dateandtime 
    FROM table.dat_access 
    WHERE cardcode = 'w123'
      and dateandtime = [dateandtime from your first query] 
    ")->row();

根据您的表结构,其中任何一个都可能返回多行。这取决于" cardcode"的组合。和" dateandtime"在你的桌子上是独一无二的。

答案 1 :(得分:0)

当您使用其中一个聚合函数(如MAX())时,您需要指定在计算该最大值(或其他值)时要包含哪些行。隐式地这是在所有返回的行上完成的,因此您的第一个查询可以正常工作。

但是在第二个查询中,您希望一个结果只提供一行(MAX(dateandtime)一个),另一个提供 n 行(snapshot)。所以它抱怨。

您现在需要明确添加GROUP BY子句,以说明应如何进行分组,因此结果是正确的。它暗示GROUP BY snapshot有意义 - 在每个结果行上,您将拥有snapshot,并且dateandtime的最大值为{。}}。

如果那不是您想要的(例如,您希望表中的所有snapshots和所有行的最大dateandtime),您将需要使用其他一些解决方案,例如两个查询或子查询