web-dev-qa-db-ja.com

Uniqueidentifierの集約関数(GUID)

次の表があるとしましょう:

category | guid
---------+-----------------------
   A     | 5BC2...
   A     | 6A1C...
   B     | 92A2...

基本的に、次のSQLを実行します。

SELECT category, MIN(guid)
  FROM myTable
 GROUP BY category

必ずしもMINである必要はありません。 one GUID各カテゴリを返します。どちらのカテゴリも気にしません。残念ながら、SQL ServerはGUIDでMINまたはMAXを許可しません。

もちろん、GUIDをvarcharに変換したり、ネストされたTOP 1 SQLを作成したりすることもできますが、これは見苦しい回避策のようです。私が見逃したエレガントなソリューションはありますか?

47
Heinzi

SQL Server 2005以降を使用している場合:

;with Numbered as (
     select category,guid,ROW_NUMBER() OVER (PARTITION BY category ORDER BY guid) rn
     from myTable
)
select * from Numbered where rn=1
32

BINARY(16)としてキャストするだけです。

SELECT category, MIN(CAST(guid AS BINARY(16)))
FROM myTable
GROUP BY category

必要に応じて、後でキャストできます。

WITH CategoryValue
AS
(    
    SELECT category, MIN(CAST(guid AS BINARY(16)))
    FROM myTable
    GROUP BY category
)
SELECT category, CAST(guid AS UNIQUEIDENTIFIER)
FROM CategoryValue
48
K Biel

SQL Serverバージョン> = 2012の場合、一意の識別子列で集計関数を使用できます

表現

定数、列名、または関数、および算術演算子、ビット単位演算子、文字列演算子の任意の組み合わせです。 MINは、数値、char、varchar、uniqueidentifier、またはdatetime列で使用できますが、ビット列では使用できません。集計関数とサブクエリは許可されていません。

18
doerig
declare @T table(category char(1), guid uniqueidentifier) 

insert into @T 
select 'a', newid() union all
select 'a', newid() union all
select 'b', newid()

select
  S.category,
  S.guid
from
(  
  select
    T.category,
    T.guid,
    row_number() over(partition by T.category order by (select 1)) as rn
  from @T as T
) as S
where S.rn = 1

SQL Server 2000を使用している場合、これを行うことができます

select 
  T1.category,
  (select top 1 T2.guid 
   from @T as T2
   where T1.category = T2.category) as guid
from @T as T1
group by T1.category   
4
Mikael Eriksson