2012-11-07 41 views
3

我有兩個表:tab1和tab2。每個表只有一個VARCHAR(MAX)列。COLLATE子句不能用於包含COLLATE子句的表達式

我只需要獲得那些相等的值對,但僅在不同情況下有所不同。

例輸入:

tab1.t1  tab2.t2 
----------------------- 
fff  fff 
FFF  fff 
Fff  fff 
FFF  FFA 
FfA  FFF 
FFF  aaa 
bbb  aaa 

Related output: 

t1  t2 
----------------------- 
fff  FFF 
FFF  fff 
Fff  fff 
Fff  FFF 
FfA  FFA 

表TAB1和TAB2在現實我們真正的數據庫(〜800-1000行)足夠大。大約有500-600列需要我做這個操作。

所以我需要寫一個快速的解決方案。 我寫alghoritm:

  1. 刪除使用來自TAB1
  2. 刪除使用區分大小寫覈對從TAB2
  3. 所有重複區分大小寫覈對所有重複使用不區分大小寫的排序規則
  4. 濾波器從前面的步驟加入的結果集(WHERE子句)行使用區分大小寫的排序規則不等於
  5. 使用區分大小寫排序規則刪除重複行

我試圖這樣:

SELECT DISTINCT tt.t1 COLLATE Cyrillic_General_CS_AS, tt.t2 COLLATE Cyrillic_General_CS_AS 
FROM (
    SELECT tt1.t1, tt2.t2 
    FROM 
    (
     SELECT tab1.t1 COLLATE Cyrillic_General_CS_AS 
         AS t1 
     FROM (VALUES('fff'),('FFF'),('Fff'),('FFF'),('FfA'),('FFF'),('bbb')) AS tab1(t1) 
     GROUP BY tab1.t1 COLLATE Cyrillic_General_CS_AS 
    ) tt1 INNER JOIN 
    (
     SELECT tab2.t2 COLLATE Cyrillic_General_CS_AS 
         AS t2 
     FROM (VALUES('fff'),('fff'),('fff'),('FFA'),('FFF'),('aaa'),('aaa')) AS tab2(t2) 
     GROUP BY tab2.t2 COLLATE Cyrillic_General_CS_AS 
    ) tt2 
    ON tt1.t1 = tt2.t2 COLLATE Cyrillic_General_CI_AS 
) AS tt 
WHERE tt.t1 <> tt.t2 COLLATE Cyrillic_General_CS_AS 

但它的錯誤發生: 「COLLATE子句不能在含有COLLATE子句表達式中使用的」

請不要使用用戶定義的函數,臨時表或刪除group by子句(我試過它們 - 它們幾乎不會減慢執行速度),以避免此問題。

回答

2

由於SQL Server可以進程加入以任何順序和任何

  1. 結轉表達式來在最終的輸出
  2. 決心表達式非常早期進行評價,早精簡到初始檢索來自數據

它不能保證它將強制應用COLLATE的階段。因此,您只能將其應用於任何列/表達式。由於在外部查詢中已經有DISTINCT,因此GROUP BY在派生表中是多餘的,即使您覺得它會減少中間結果集。


SELECT DISTINCT tt.t1 COLLATE Cyrillic_General_CS_AS, tt.t2 COLLATE Cyrillic_General_CS_AS 
FROM (
    SELECT tt1.t1, tt2.t2 
    FROM 
     (VALUES('fff'),('FFF'),('Fff'),('FFF'),('FfA'),('FFF'),('bbb')) tt1(t1) 
    INNER JOIN 
     (VALUES('fff'),('fff'),('fff'),('FFA'),('FFF'),('aaa'),('aaa')) tt2(t2) 
    ON tt1.t1 = tt2.t2 
) AS tt 
WHERE tt.t1 <> tt.t2 COLLATE Cyrillic_General_CS_AS