使用 Group By 选择无法正常工作

Posted

技术标签:

【中文标题】使用 Group By 选择无法正常工作【英文标题】:Select with Group By not working properly 【发布时间】:2015-10-02 02:21:28 【问题描述】:

我正在开发一个需要嵌入式数据库的应用程序,因此我使用 mysql 对其进行了设计,并创建了一个可以在其中工作的 SQL 语句。但是,当迁移到嵌入式数据库(即 Hyper-SQL (HSQLDB))时,我的查询不再起作用。这似乎与我在选择上必须与 Group By 匹配的参数数量有关,但如果我去添加它们,它将保持数据未分组,这对我不起作用。

这里是查询:

我有两个具有相同列的表(GFS 和 SUPP),不同之处在于行为,一个比另一个具有更多填充的列。

SELECT gfs.GFSAccount, gfs.GLAccount,
       CASE 
         WHEN gfs.ICPartner = "" THEN '[ICP_NONE]'
         WHEN gfs.ICPartner <> "" THEN gfs.ICPartner
       END AS ICPartner,
       CASE 
         WHEN gfs.PPESupplementalData <> '' THEN gfs.PPESupplementalData
         WHEN gfs.PPESupplementalData = '' THEN '[NONE]'
       END AS SupplementalData,
       CASE 
         WHEN gfs.AccountType = 'SALES AND COS' THEN gfs.PCode
         WHEN gfs.AccountType = 'COO' THEN 'COO'
         WHEN gfs.AccountType = 'OTHERS' THEN gfs.Business
       END AS Business,
       Round(Sum(gfs.Amount), 2) AS Amount
FROM gfs, supp
WHERE gfs.GLAccount <> supp.GLAccount
GROUP BY gfs.GFSAccount,
         CASE WHEN gfs.ICPartnerSplit = 1 THEN gfs.ICPartner END

UNION

SELECT GFSAccount, GLAccount,
       CASE 
         WHEN ICPartner = "" THEN '[ICP_NONE]'
         WHEN ICPartner <> "" THEN ICPartner
       END AS ICPartner,
       CASE 
         WHEN SuppData <> '' THEN SuppData
         WHEN SuppData = '' THEN '[NONE]'
       END AS SupplementalData,
       Business, Round(Sum(Amount), 2) AS Amount
FROM supp

ORDER BY GFSAccount;

空白和固定字段有很多转换,但主要问题是 3 group by(每个选择中有 2 个,最后一个),它不允许我这样做。

(我知道查询本身并不是最好的创建或优化的,但我已经离开数据库一段时间了,我有点生疏了)

你们有什么建议可以让我在 HSQLDB(或其他不是 MySQL 的数据库)中工作吗??

【问题讨论】:

考虑编辑您的问题并格式化您的查询。 “不再工作”不是您能提供的最佳信息。并且确切地解释查询应该做什么总是有帮助的。 似乎是另一个 MySQL 的流氓实现 GROUP BY 咬你的例子。在标准 SQL 中,所有未在 GROUP BY 子句中列出的列(在功能上不相关)都必须是聚合的一部分。 MySQL 只是从每个组中选择任意一行。 Postgres 遵循标准(大部分),按主键分组覆盖表的其余部分,未观察到其他功能依赖关系。相关答案here或here。 我想我也会担心您的加入会为您提供(几乎)笛卡尔积。将不相关的帐户相加有什么意义? 不相关,但是:gfs.ICPartner = "" 也是无效的(标准)SQL。字符串文字需要单引号,而不是双引号。双引号用于在 SQL 中引用标识符。因此,该条件是将列 ICPartner 与具有空白名称的列(肯定不存在)进行比较 【参考方案1】:

看来您想从gfs 表中选择数据,但前提是GLAccount 不存在于supp 表中。你需要一个LEFT JOIN 来做到这一点。否则,您需要GROUP BYsum() 函数中未使用的所有列。您可以简化您的CASE 语句。对于 PostgreSQL,查询如下所示:

SELECT gfs.GFSAccount, gfs.GLAccount,
       CASE gfs.ICPartner
         WHEN '' THEN '[ICP_NONE]' ELSE gfs.ICPartner
       END AS ICPartner,
       CASE gfs.PPESupplementalData
         WHEN '' THEN '[NONE]' ELSE gfs.PPESupplementalData
       END AS SupplementalData,
       CASE gfs.AccountType
         WHEN 'SALES AND COS' THEN gfs.PCode
         WHEN 'COO' THEN 'COO'
         WHEN 'OTHERS' THEN gfs.Business
       END AS Business,
       round(sum(gfs.Amount), 2) AS Amount
FROM gfs
LEFT JOIN supp USING (GLAccount)
WHERE supp.GLAccount IS NULL
GROUP BY 1, 2, 3, 4, 5, 6

UNION

SELECT GFSAccount, GLAccount,
       CASE ICPartner
         WHEN '' THEN '[ICP_NONE]' ELSE ICPartner
       END AS ICPartner,
       CASE SuppData
         WHEN '' THEN '[NONE]' ELSE SuppData
       END AS SupplementalData,
       Business, round(sum(Amount), 2) AS Amount
FROM supp
GROUP BY 1, 2, 3, 4, 5, 6

ORDER BY GFSAccount;

如果各个列是NULL 而不是空字符串'',则应将CASE 语句更改为coalesce(gfs.ICPartner, '[ICP_NONE]') AS ICPartner 等。

【讨论】:

只是一个问题,GROUP BY 中的数字是指什么? @jarlh: 选择列表中的列索引

以上是关于使用 Group By 选择无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01446 - 无法使用 DISTINCT、GROUP BY 等从视图中选择 ROWID

如何解决 Oracle Apex 中的“无法使用 DISTINCT、GROUP BY 等从视图中选择 FOR UPDATE”错误?

oracle查询选择语句——count、sum、order by、group by

RTL 布局中的引导日期选择器无法正常工作

Livewire 电线:选择选项上的模型无法正常工作

GROUP CONCAT 由于某种原因无法正常工作