【问题标题】:SQL IIF group by result in MS Access 2007SQL IIF 按 MS Access 2007 中的结果分组
【发布时间】:2011-02-13 02:03:45
【问题描述】:

我正在使用一些我认为应该可以工作的 SQL。但是我很快了解到 MS Access 对如何使用 SQL 有自己的想法。

SELECT count([system_info].[id]) as CountofID,
IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 512000, "<512mb", 
IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 1000000, "512mb - 1GB", "nope")) as MemoryText
FROM system_info
GROUP BY MemoryText;

所以上面的代码给了我错误消息“你试图执行一个查询,它不包括指定的表达式 XXX 作为聚合函数的一部分”。

我已经用谷歌搜索了很多,但仍然很卡住。如果我删除计数和 groupBY,查询将运行,我会看到我为“MemoryText”创建的标签列表。

感谢您的帮助。

【问题讨论】:

    标签: sql ms-access ms-access-2007


    【解决方案1】:

    如果我删除计数和 groupBY,查询将运行,我会看到我为“MemoryText”创建的标签列表。

    在这种情况下,保存作为 qryBase 工作的版本:

    SELECT [system_info].[id]),
    IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 512000, "<512mb", 
    IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 1000000, "512mb - 1GB", "nope")) as MemoryText
    FROM system_info;
    

    那么你的聚合查询可以是:

    SELECT MemoryText, count(id) as CountofID
    FROM qryBase
    GROUP BY MemoryText;
    

    编辑:但是,这个表达让我很困惑:

    Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 512000
    

    我预期的不是 512000,而是 524288 (512 * 1024)。

    Left() 的输出将是字符串,因此您的表达式将字符串与数字进行比较。虽然数据库引擎可能会在比较之前将字符串转换为数字,但我会明确地这样做。

    Val(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)) < 524288
    

    如果您告诉我们您的 CSMemory 字段的数据类型并向我们展示一些示例值,您可能会得到更好的建议。

    Edit2:来自 Access 的帮助:Val 函数在它无法识别为数字的一部分的第一个字符处停止读取字符串。

    所以 Val("2052644 KB") 将忽略非数字字符并为您提供数字 2052644。但是,您的示例值还包括逗号,因此 Val() 将在第一个逗号处停止读取 ... Val( "2,052,644 KB") 会给你 2。

    如果您的查询是在 Access 2000 或更高版本的 Access 会话中运行的,您可以在使用 Val() 评估文本之前使用 Replace() 函数去除逗号(用零长度字符串替换逗号)。在即时窗口中:

    ? Replace("2,052,644 KB", ",", "")
    2052644 KB
    
    ? Val(Replace("2,052,644 KB", ",", ""))
     2052644 
    

    因此,您可以使用以下方法,而不是使用 Left() 和 Len():

    Val(Replace(CSMemory, ",", ""))  < 512000
    

    【讨论】:

    • 谢谢。内存在数据库中保存为字符串(不是我的设计!),例如,'2,052,644 KB'、'490,992 KB' - 我使用 left() 函数仅删除数字(通过去掉三个字符在最后)。似乎工作正常。我试试你的方法,看看能不能保存。
    • @Matt Facer 我编辑了答案以提出一种从 CSMemory 文本中提取数字的不同方法。在我看来,它不像 Left() 和 Len() 那样麻烦。
    【解决方案2】:

    您需要将整个 Memory Text 表达式放在 GROUP BY 语句中

    SELECT count([system_info].[id]) as CountofID,
    IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 512000, "<512mb", 
    IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 1000000, "512mb - 1GB", "nope")) as MemoryText
    FROM system_info
    GROUP BY IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 512000,
    "<512mb", 
    IIF(Left([system_info].[CSMemory],Len([system_info].[CSMemory])-3)  < 1000000, "512mb - 1GB", "nope"))
    

    【讨论】:

    • 我相信在大多数 SQL 中,您不能在 Order By 子句之前引用别名 (MemoryText)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多