Доступ к SQL для получения количества значений, соответствующих условию - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь написать запрос в Access, который будет возвращать количество значений для каждого сайта в таблице, где значение превышает указанный уровень, а также для сайтов, у которых нет значений, превышающих этот уровень, возвращать указанныйзначение, например "NA".

Я пробовал Iif, Switch, Union, подзапросы, запрашивая другой запрос, но не повезло.Я могу получить все значения, превышающие уровень, или все сайты с "NA" правильными, но показывающими общее количество для остальных, а не только счет выше уровня.

Например, в таблице ниже, предполагая уровень>10, Хьюстон = "NA", Детройт = 2, Питтсбург, Пенсильвания = 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 |
+-----------------+-------+

Ответы [ 4 ]

0 голосов
/ 13 февраля 2019

Просто используйте условное агрегирование:

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;
0 голосов
/ 13 февраля 2019

Другое решение заключается в использовании условного агрегирования, как указано ниже:

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

Этот подход должен быть более эффективным, чем самостоятельное присоединение к таблице, поскольку он требует сканирования таблицы только один раз.

SUM(IIf ...) - это удобная конструкция для подсчета количества записей, удовлетворяющих данному условию.

Примечание: обычно не рекомендуется возвращать два разных типа данных в одном столбце (в вашем случае использованиялибо число, либо строка 'NA').Большинство СУБД не позволяют этого.Поэтому я предоставил запрос, который будет возвращать 0, когда нет совпадений, вместо NA.Если вы действительно хотите 'NA', вы можете попробовать:

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

Эта демонстрация на DB Fiddle , с вашими примерами возврата:

site       | value
:--------- | ----:
Detroit    |     2
Houston    |     0
Pittsburgh |     3
0 голосов
/ 13 февраля 2019

Вы можете использовать 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 делает это неявно для вас.

0 голосов
/ 13 февраля 2019
  1. Получите список всех сайтов, не зависящих от количества (таблица производная от SiteList ниже)
  2. ВЛЕВО Присоедините это обратно к вашей базовой таблице (SiteValues), чтобы получить количество для каждого сайта, где находится порог встречи,--note должен присоединиться к ключу, который я не уверен, что для этой таблицы.одного сайта недостаточно
  3. Подсчитайте значения из набора данных siteValues, поскольку значения NULL будут считаться равными 0.

WORKING 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, вы должны бросить счет в варчар

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...