列必须出现在GROUP BY子句中,或者被用于聚合函数。

4

我正在更新一个Qt软件,使其与SQLite和PostgreSQL兼容。我有一个C++方法,用于计算给定表中带有给定限制条件的元素数量。

在SQLite中,以下内容有效并提供了数字N(计数)。

SELECT COUNT(*) FROM table_a 
INNER JOIN table_b AS
ON table_b.fk_table_a = table_a.id
WHERE table_a.start_date_time <> 0
ORDER BY table_a.creation_date_time DESC

使用PostgreSQL(我使用的是9.3版本)时,出现以下错误:
ERROR: 列“table_a.creation_date_time”必须出现在GROUP BY子句中或用于聚合函数 LINE 5: ORDER BY table_a.creation_date_time DESC
如果添加“GROUP BY table_a.creation_date_time”,它会给出一个N行的表格。我阅读了很多关于不同DBMS允许你在GROUP BY子句中省略列的内容。现在,我感到很困惑。
对于那些好奇的人,C++方法是:
static int count(const QString &table, const QString &clauses = QString(""))
{
    int success = -1;

    if (!table.isEmpty())
    {
        QString statement = QString("SELECT COUNT(*) FROM ");
        statement.append(table);
        if (!clauses.isEmpty())
        {
            statement.append(" ").append(clauses)   ;
        }
        QSqlQuery query;
        if(!query.exec(statement))
        {
            qWarning() << query.lastError();
            qWarning() << statement;
        }
        else
        {
            if (query.isActive() && query.isSelect() && query.first())
            {
                bool ok = false;
                success = query.value(0).toInt(&ok);
                if (ok == false)
                {
                    success = -1;
                    return success;
                }
            }
        }
    }

    return success;
}

那么SQLite和MySQL都是“轻松自如”的。 - Michel L
1个回答

1
如果你只是在表上执行count(*)以获取单个标量值结果,那么有order by是否存在就无关紧要了吧?
解决方案
删除过时的order by,以获得跨多个dbms的“标准”查询行为。

2
妻子:我渴了。我:这是一杯水。妻子:我没要一杯水,我想让你能够理解我的口渴问题。我:对不起宝贝,我只关注解决问题。 - Eoin Campbell
Campbell,我发现如果我删除ORDER BY table_a.creation_date_time DESC,它就可以工作。问题在于,当调用该方法时,clauses参数已经包含了GROUP BY语句。也许我应该在每次调用该方法之前删除这个语句,因为正如你所说,每次调用它时我只需要一个单一的标量值。 - Michel L
懦弱的评论删除 @a_horse_with_no_name ;-) - Eoin Campbell
1
我不知道@a_horse_with_no_name的评论出了什么问题。当我回答时,我看到它已经被删除了。他引用了我的话告诉我MySQL在处理GROUP BY语句时是“宽松的”,这被一些人认为是一个错误或类似的东西。 - Michel L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接