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
どのようなクエリがこの情報を出力しますか?
これは、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
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
更新:マーティンの代替案は非常に効率的です。
ここに、マーティンのソリューションに対する別の同様のアプローチがあります。
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]);