Укажите MAX и MIN в одном столбце на сервере SQL - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь перечислить округ с самым высоким уровнем бедности и с самым низким уровнем бедности в той же колонке рядом с государством, которому принадлежит каждый. Например:

+----------+--------+--------------+
| State    | County | Poverty Rate |
+----------+--------+--------------+
| Delaware | AB     | 0.1234       |
+----------+--------+--------------+
| Delaware | CD     | 0.6789       |
+----------+--------+--------------+
| Virginia | EF     | 0.1357       |
+----------+--------+--------------+
| Virginia | GH     | 0.4680       |
+----------+--------+--------------+

Но я получил только три столбца: «Состояние», «Самый высокий уровень бедности», «Самый низкий уровень бедности», с кодом ниже:

;WITH poverty_CTE AS (
    SELECT
        state
        ,County
        ,AVG(pctPoor)    AS 'Poverty'
    FROM [SQLBook].[dbo].[ZipCensus]
    WHERE County IS NOT NULL
    GROUP BY County, state
)
SELECT
    CASE state
        WHEN '10' THEN 'Delaware'
        WHEN '51' THEN 'Virginia'
        ELSE 'Others'
    END                     AS State
    ,MAX(Poverty)           AS 'Highest Poverty Rate'
    ,MIN(Poverty)           AS 'Lowest Poverty Rate'
FROM poverty_CTE
WHERE state IN (10, 51)
GROUP BY State
ORDER BY State

Это результат:

+------------+----------------------+---------------------+
| State      | Highest Poverty Rate | Lowest Poverty Rate |
+------------+----------------------+---------------------+
| Delaware   | 0.6789               | 0.1234              |
+------------+----------------------+---------------------+
| Washington | 0.4680               | 0.1357              |
+------------+----------------------+---------------------+

Можно ли достичь того, что я хочу, без сложных подзапросов?

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Использование оконных функций:

SELECT state_name, county, poverty_rate
FROM (SELECT (CASE state WHEN '10' THEN 'Delaware' WHEN '51' THEN 'Virginia' END) as state_name,
             County, AVG(pctPoor) as poverty_rate,
             ROW_NUMBER() OVER (PARTITION BY state ORDER BY AVG(pctPoor) ASC) as seqnum_asc,
             ROW_NUMBER() OVER (PARTITION BY state ORDER BY AVG(pctPoor) DESC) as seqnum_desc
      FROM [SQLBook].[dbo].[ZipCensus]
      WHERE County IS NOT NULL AND state IN ('10', '51')
      GROUP BY County, state
     ) s
WHERE 1 IN (seqnum_asc, seqnum_desc)
ORDER BY state_name, poverty_rate;

Обратите внимание, что подзапрос выполняет большую работу - нет необходимости в большом количестве CTE и подзапросов:

  • It заменяет код именем состояния.
  • Фильтрует данные перед агрегированием (что более эффективно) для двух требуемых состояний.
  • Назначает порядковые номера определить лучшие и худшие страны.

Вероятно, вы должны использовать справочную таблицу для поиска имен состояний.

0 голосов
/ 04 мая 2020

Вот ответ на ваш вопрос ... с подзапросами:

create table dbo.ZipCensus (
  State int,
  County varchar(20),
  pctPoor float
);

insert dbo.ZipCensus (State, County, pctPoor) values
  (10, 'AB', 0.1234),
  (10, 'CD', 0.6789),
  (51, 'EF', 0.1357),
  (51, 'GH', 0.4680);

select State, County, [Poverty Rate]
from (
  select
    S.State,
    County,
    [Poverty Rate],
    LeastPoor = row_number() over (partition by P.State order by [Poverty Rate] asc, County asc),
    MostPoor = row_number() over (partition by P.State order by [Poverty Rate] desc, County asc)
  from (
    select State, County, avg(pctPoor) as [Poverty Rate]
    from dbo.ZipCensus
    where State in (10, 51)
    group by State, County
  ) P
  join (values
    (10, 'Delaware'),
    (51, 'Virginia')
  ) S (StateID, State) on S.StateID=P.State
) R
where LeastPoor=1 or MostPoor=1
order by State, [Poverty Rate]

Что дает результат:

State   County  Poverty Rate
Delaware    AB  0.1234
Delaware    CD  0.6789
Virginia    EF  0.1357
Virginia    GH  0.468
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...