【问题标题】:Access sql to retrieve counts of values meeting a condition访问 sql 以检索满足条件的值的计数
【发布时间】:2019-07-07 19:09:28
【问题描述】:

我正在尝试在 Access 中编写一个查询,该查询将返回表中每个站点的值计数,其中值超过指定级别,而且对于没有超过该级别的值的站点,返回指定的值,例如"NA"。

我试过Iif、Switch、Union,子查询,查询不同的查询,但没有运气。我可以得到所有超过该级别的计数,或者所有带有"NA" 的站点都正确但显示其余的总计数,而不仅仅是高于该级别。

例如,在下表中,假设级别 > 10,Houston = "NA",Detroit = 2,Pittsburgh PA = 3。我只是无法让查询的双方都工作。

提前为格式不佳道歉。

+-----------------+-------+
|     1. Site     | Value |
+-----------------+-------+
|  2. Houston     |    10 |
|  3. Houston     |     3 |
|  4. Houston     |     0 |
|  5. Detroit     |    15 |
|  6. Detroit     |     7 |
|  7. Detroit     |     4 |
|  8. Detroit     |    12 |
|  9. Pittsburgh  |    23 |
|  10. Pittsburgh |     2 |
|  11. Pittsburgh |    18 |
|  12. Pittsburgh |    12 |
+-----------------+-------+

【问题讨论】:

  • 你能发布一些你的查询吗?
  • 发布您尝试过的 SQL、获得的结果以及您期望获得的结果以及示例数据通常是明智的。这有助于我们了解您的问题以及您想要做什么,而无需提出一堆额外的问题。
  • 部分问题是数据类型 'NA' 不是数字,而 count 是,并且列不能既是数字又是字符;只是其中之一.. 0 和 NA 一样好用吗?
  • 我使用的是 NA 而不是 0,因为 0 表示不存在值(这些值是检测到的化学量),而 NA 表示未发现,但化学物质的含量可能低于测试检测限。差别不大,但这是我们的工作场所报告标准。
  • 那么您需要将 sum/count 转换为 varchar 以支持 NA。

标签: sql ms-access count


【解决方案1】:

另一种解决方案是使用条件聚合,如下:

SELECT site, SUM(IIf(value > 10, 1, 0)) AS value
FROM mytable
GROUP BY site

这种方法应该比自连接表更有效,因为它只需要扫描一次表。

SUM(IIf ...) 是一个方便的构造,用于计算有多少记录满足给定条件。

注意:在同一列中返回两种不同的数据类型通常不是一个好主意(在您的用例中,可以是数字或字符串'NA')。大多数 RDBMS 不允许这样做。所以我提供了一个查询,当没有匹配项时将返回0,而不是NA。如果你真的想要'NA',你可以试试:

IIF(
    SUM(IIf(value > 10, 1, 0)) = 0, 
    'NA', 
    STR(SUM(IIf(value > 10, 1, 0)))
) AS value

这个demo on DB Fiddle,连同你的样本数据返回:

网站 |价值 :--------- | ----: 底特律 | 2 休斯顿 | 0 匹兹堡 | 3

【讨论】:

  • @Rene:对。我将查询改为使用IIf...感谢您指出这一点!
【解决方案2】:
  1. 获取与计数无关的所有站点的列表(下面的 SiteList 派生表)
  2. LEFT 将此连接回您的基表 (SiteValues) 以获取每个站点的计数,其中它满足阈值。 --note 应该加入我不确定这个表是什么的键。仅网站是不够的
  3. 将 siteValues 数据集中的值计数为 NULL 将被计为 0。

工作DEMO: .

SELECT SiteList.Site, Count(Sitevalues.Site)
FROM (SELECT site, value
      FROM TableName) SiteList
LEFT JOIN TableName SiteValues
 on SiteList.Site = SiteValues.Site
 and SiteValues.Value > 10
 and SiteValues.Value = SiteList.value
GROUP BY SiteList.Site

给我们:

+----+------------+------------------+
|    |    Site    | (No column name) |
+----+------------+------------------+
|  1 | Detroit    |                2 |
|  2 | Houston    |                0 |
|  3 | Pittsburgh |                3 |
+----+------------+------------------+

或者,如果您需要 NA,则必须将计数转换为 varchar

SELECT SiteList.Site, case when Count(Sitevalues.Site) = 0 then 'NA' else cast(count(Sitevalues.site) as varchar(10)) end as SitesMeetingThreshold
FROM (SELECT site, value
      FROM TableName) SiteList
LEFT JOIN TableName SiteValues
 on SiteList.Site = SiteValues.Site
 and SiteValues.Value > 10
 and SiteValues.Value = SiteList.value
GROUP BY SiteList.Site

【讨论】:

    【解决方案3】:

    只使用条件聚合:

    select site,
           max(iif(value > 10, 1, 0)) as cnt_11plus
    from t
    group by site;
    

    我认为0 比N/A 好。但是,如果您愿意,您需要将结果转换为字符串。

    select site,
           iif(max(iif(value > 10, 1, 0)) > 0,
               str(max(iif(value > 10, 1, 0))),
               "N/A"
              ) as cnt_11plus
    from t
    group by site;
    

    【讨论】:

      【解决方案4】:

      你可以像这样使用UNION:

      SELECT site, count(value) AS counter
      FROM sites
      WHERE value > 10
      GROUP BY site
      UNION
      SELECT s.site, 'NA' AS counter
      FROM sites AS s
      WHERE value <= 10
      AND NOT EXISTS (
        SELECT 1 FROM sites WHERE site = s.site AND value > 10  
      )
      GROUP BY site
      

      结果:

      site        counter
      Detroit     2
      Houston     NA
      Pittsburgh  3
      

      无需将整数计数器转换为Text,因为Access 会为您隐式执行此操作。

      【讨论】:

        猜你喜欢
        • 2019-07-15
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 2017-05-20
        • 2014-01-21
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多