簡體   English   中英

如何確定表是否具有一些唯一列

[英]How to find out whether a table has some unique columns

我使用MS SQL Server。

我已經交了一些沒有約束的大桌子,沒有鑰匙也沒有。

我知道有些列具有唯一值。 對於給定的表,是否有一種聰明的方法來查找具有唯一值的cols?

現在,我通過計算是否存在與表中的行一樣多的DISTINCT值來手動為每列執行此操作。

SELECT COUNT(DISTINCT col) FROM table

可能會讓一個cusor循環遍歷所有列,但想聽聽是否有人知道更聰明或內置函數。

謝謝。

這是一種基本類似於@JNK的方法,但它不是打印計數,而是為每個列返回一個現成的答案,告訴您列是否僅包含唯一值:

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);

它只是將COUNT(DISTINCT column)與每列的COUNT(*)進行比較。 結果將是一個包含單行的表,其中每列將包含不具有重復項的列的值UNIQUE ,如果存在重復項,則為空字符串。

但上述解決方案僅適用於那些沒有NULL的列。 應該注意,當您要在列上創建唯一約束/索引時,SQL Server不會忽略NULL。 如果一列只包含一個NULL且所有其他值都是唯一的,您仍然可以在列上創建一個唯一約束(但不能使它成為主鍵,這需要值的唯一性和缺少NULL)。

因此,您可能需要對內容進行更全面的分析,您可以使用以下腳本獲得:

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);

此解決方案通過檢查三個值來考慮NULL: COUNT(DISTINCT column)COUNT(column)COUNT(*) 它顯示的結果與前一種解決方案類似,但列的可能診斷更加多樣化:

  • UNIQUE表示沒有重復值且沒有NULL(可以是PK或具有唯一約束/索引);

  • UNIQUE WITH SINGLE NULL - 可以猜到,沒有重復,但是有一個NULL(不能是PK,但可以有唯一的約束/索引);

  • UNIQUE with NULLs - 沒有重復項,兩個或多個NULL(如果你在SQL Server 2008上,你可以只有非NULL值的條件唯一索引);

  • 空字符串 - 有重復項,也可能是NULL。

我想這可能是最干凈的方式。 只需使用動態sql和單個select語句來創建一個查詢,該查詢為每個字段提供總行數和不同值的計數。

在頂部填寫數據庫名稱和表名。 數據庫名稱部分非常重要,因為OBJECT_NAME僅適用於當前數據庫上下文。

use DatabaseName

DECLARE @Table varchar(100) = 'TableName'

DECLARE @SQL Varchar(max)

SET @SQL = 'SELECT COUNT(*) as ''Total'''

SELECT @SQL = @SQL + ',COUNT(DISTINCT ' + name + ') as ''' + name + ''''
FROM sys.columns c
WHERE OBJECT_NAME(object_id) = @Table

SET @SQL = @SQL + ' FROM ' + @Table

exec @sql

如果您使用的是2008,則可以使用SSIS中的數據概要分析任務返回每個表的候選密鑰。

這篇博客文章介紹了這個過程,它非常簡單:

http://consultingblogs.emc.com/jamiethomson/archive/2008/03/04/ssis-data-profiling-task-part-8-candidate-key.aspx

我的代碼做了幾句話:

  1. 讀取所有表格和列

  2. 創建臨時表以保存具有重復鍵的表/列

  3. 對於每個表/列,它運行查詢。 如果它為至少一個值找到count(*)> 1,則它會插入臨時表

  4. 從系統表中選擇與發現具有重復項的表/列不匹配的列和值

     DECLARE @sql VARCHAR(max) DECLARE @table VARCHAR(100) DECLARE @column VARCHAR(100) CREATE TABLE #temp (tname VARCHAR(100),cname VARCHAR(100)) DECLARE mycursor CURSOR FOR select t.name,c.name from sys.tables t join sys.columns c on t.object_id = c.object_id where system_type_id not in (34,35,99) OPEN mycursor FETCH NEXT FROM mycursor INTO @table,@column WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = 'INSERT INTO #temp SELECT DISTINCT '''+@table+''','''+@column+ ''' FROM ' + @table + ' GROUP BY ' + @column +' HAVING COUNT(*)>1 ' EXEC (@sql) FETCH NEXT FROM mycursor INTO @table,@column END select t.name,c.name from sys.tables t join sys.columns c on t.object_id = c.object_id left join #temp on t.name = #temp.tname and c.name = #temp.cname where system_type_id not in (34,35,99) and #temp.tname IS NULL DROP TABLE #temp CLOSE mycursor DEALLOCATE mycursor 

簡單的一行代碼怎么樣:

CREATE UNIQUE INDEX index_name ON table_name (column_name);

如果創建了索引,則column_name僅具有唯一值。 如果column_name中存在欺騙,則會收到錯誤消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM