Aquí es un enfoque que es básicamente similar a @ JNK, pero en lugar de imprimir los recuentos devuelve una respuesta para cada columna que indica si una columna se compone de valores únicos única o no:
DECLARE @table varchar(100), @sql varchar(max);
SET @table = 'some table name';
SELECT
@sql = COALESCE(@sql + ', ', '') + ColumnExpression
FROM (
SELECT
ColumnExpression =
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(*) THEN ''UNIQUE'' ' +
'ELSE '''' ' +
'END AS ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
) s
SET @sql = 'SELECT ' + @sql + ' FROM ' + @table;
PRINT @sql; /* in case you want to have a look at the resulting query */
EXEC(@sql);
Simplemente compara COUNT(DISTINCT column)
con COUNT(*)
para cada columna. El resultado será una tabla con una sola fila, donde cada columna contendrá el valor UNIQUE
para aquellas columnas que no tienen duplicados, y una cadena vacía si hay duplicados presentes.
Pero la solución anterior funcionará correctamente solo para aquellas columnas que no tienen valores NULL.Cabe señalar que SQL Server no ignora los NULL cuando se desea crear una restricción/índice único en una columna. Si una columna contiene solo un NULL y todos los demás valores son únicos, aún puede crear una restricción única en la columna (sin embargo, no puede convertirla en clave primaria, lo que requiere tanto la uniquness de valores como la ausencia de valores NULL).
Por lo tanto es posible que necesite un análisis más exhaustivo de los contenidos, que se podría obtener con la siguiente secuencia de comandos:
DECLARE @table varchar(100), @sql varchar(max);
SET @table = 'some table name';
SELECT
@sql = COALESCE(@sql + ', ', '') + ColumnExpression
FROM (
SELECT
ColumnExpression =
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(*) THEN ''UNIQUE'' ' +
'WHEN COUNT(*) - 1 THEN ' +
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(' + COLUMN_NAME + ') THEN ''UNIQUE WITH SINGLE NULL'' ' +
'ELSE '''' ' +
'END ' +
'WHEN COUNT(' + COLUMN_NAME + ') THEN ''UNIQUE with NULLs'' ' +
'ELSE '''' ' +
'END AS ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
) s
SET @sql = 'SELECT ' + @sql + ' FROM ' + @table;
PRINT @sql; /* in case you still want to have a look at the resulting query */
EXEC(@sql);
Esta solución toma valores NULL en cuenta por el control de tres valores: COUNT(DISTINCT column)
, COUNT(column)
y COUNT(*)
. Se muestra los resultados de manera similar a la primera solución, pero los posibles diagnósticos para las columnas son más diversos:
UNIQUE
significa que no hay valores duplicados y no hay valores NULL (puede ser o bien un PK o tener una restricción única/index) ;
UNIQUE WITH SINGLE NULL
- como se puede adivinar, no hay duplicados, pero hay uno NULO (no puede ser un PK, pero puede tener una restricción/índice único);
UNIQUE with NULLs
- no hay duplicados, dos o más valores NULL (en caso de que esté en SQL Server 2008, podría tener un índice único condicional solo para valores que no sean NULL);
cadena vacía - hay duplicados, posiblemente NULL también.
dando error "Advertencia: el valor nulo es eliminado por un agregado u otra operación SET". No se puede usar desde la aplicación. – ratneshsinghparihar
@ user998660: "De la aplicación particularmente sensible a las advertencias", ¿quiere decir? En ese caso, no, no puede, por supuesto. No todas las aplicaciones * son * tan sensibles, sin embargo. Por ejemplo, no recuerdo haber tenido problemas en Delphi con agregados que producen tales advertencias. De todos modos, mi impresión fue que OP deseaba una solución que pudieran usar "manualmente", por ejemplo, en el caso de una consulta, invocándola en una herramienta como SSMS. –