web-dev-qa-db-ja.com

カウントの最大値と最小値を持つ行を選択するにはどうすればよいですか?

SQL Server 2012に次の表があります。

CREATE TABLE [MyTable] (
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(),
    [MyGroup] INT NOT NULL
);

フォームの表を出力したい

    | MyGroup | Count
Max |         |
Min |         |

たとえば、MyGroup = 30であるMyTable = 1行、MyGroup = 20である2行、およびMyGroup = 10である3行がある場合、

    | MyGroup | Count
Max | 1       | 30
Min | 3       | 10

どのようなクエリがこの情報を出力しますか?

1
cubetwo1729

これは、COUNTを両方向にソートする必要を回避するTravisの回答の別の定式化です。

WITH s
     AS (SELECT MyGroup,
                Count(MyGroup)              AS [Count],
                MAX(Count(MyGroup)) OVER () AS [MaxMyGroup],
                MIN(Count(MyGroup)) OVER () AS [MinMyGroup]
         FROM   MyTable
         GROUP  BY MyGroup)
SELECT Agg,
       MyGroup,
       V.[Count]
FROM   s
CROSS APPLY (VALUES ( 'Max', CASE WHEN [Count] = [MaxMyGroup] THEN [Count] END),
                     ('Min', CASE WHEN [Count] = [MinMyGroup] THEN [Count] END))
             V(Agg, [Count])
WHERE V.[Count] IS NOT NULL       
7
Martin Smith
WITH s AS (
  SELECT MyGroup, Count(MyGroup) AS [Count], 
  RANK() OVER (ORDER BY Count(MyGroup)) AS [rasc],
  RANK() OVER (ORDER BY Count(MyGroup) DESC) AS [rdesc]
FROM MyTable
GROUP BY (MyGroup)
)
SELECT 
  CASE 
    WHEN [rasc] = 1 THEN 'Min'
    ELSE 'Max' 
  END AS 'Agg',
  [MyGroup], 
  [Count]
FROM s
WHERE [rasc] = 1 OR [rdesc] = 1

SQLFiddle

更新:マーティンの代替案は非常に効率的です。

ここに、マーティンのソリューションに対する別の同様のアプローチがあります。

WITH s AS (
SELECT MyGroup, Count(MyGroup) AS [Count], 
  MAX(Count(MyGroup)) OVER () AS [Max],
  MIN(Count(MyGroup)) OVER () AS [Min]
FROM MyTable
GROUP BY MyGroup
)
SELECT 
  CASE 
    WHEN [Count] = [Max] THEN 'Max'
    ELSE 'Min' 
  END AS [Agg],
  [MyGroup], 
  [Count]
FROM s
WHERE [Count] IN ([Max], [Min]);
6
Travis