web-dev-qa-db-fra.com

Fonction d'agrégation sur Uniqueidentifier (GUID)

Disons que j'ai le tableau suivant:

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

Fondamentalement, je veux faire le SQL suivant:

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

Il ne doit pas nécessairement être MIN. Je veux juste retourner n GUID de chaque catégorie. Je m'en fiche de laquelle. Malheureusement, SQL Server n'autorise pas MIN ou MAX sur les GUID.

Bien sûr, je pourrais convertir le guid en varchar, ou créer un TOP 1 SQL imbriqué, mais cela semble être une solution de contournement laide. Y a-t-il une solution élégante que j'ai ratée?

47
Heinzi

En supposant que vous utilisez SQL Server 2005 ou version ultérieure:

;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

Il suffit de le convertir en BINARY(16).

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

Vous pouvez le restaurer ultérieurement si nécessaire.

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

Les fonctions d'agrégation peuvent être utilisées sur les colonnes Uniqueidentifier si la version SQL Server> = 2012

expression

Est une constante, un nom de colonne ou une fonction, et toute combinaison d'opérateurs arithmétiques, au niveau du bit et de chaîne. MIN peut être utilisé avec des colonnes numériques, char, varchar, uniqueidentifier ou datetime, mais pas avec des colonnes de bits. Les fonctions d'agrégation et les sous-requêtes ne sont pas autorisées.

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

Si vous êtes sur SQL Server 2000, vous pouvez

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