T-SQL对不同行中MAX长度列的行进行分组(?)

时间:2009-06-26 10:27:19

标签: sql sql-server sql-server-2005 tsql

我正试图想出一种基于行键基于任何行中最长字符串组合表中行的方法

例如

CREATE TABLE test1 
    (akey int not null , 
    text1 varchar(50) NULL, 
    text2 varchar(50) NULL, 
    text3 varchar(50) NULL  )


INSERT INTO test1 VALUES ( 1,'Winchester Road','crawley',NULL)
INSERT INTO test1 VALUES ( 1,'Winchester Rd','crawley','P21869')
INSERT INTO test1 VALUES ( 1,'Winchester Road','crawley estate','P21869')
INSERT INTO test1 VALUES ( 1,'Winchester Rd','crawley','P21869A')
INSERT INTO test1 VALUES ( 2,'','birmingham','P53342B')
INSERT INTO test1 VALUES ( 2,'Smith Close','birmingham North East','P53342')
INSERT INTO test1 VALUES ( 2,'Smith Cl.',NULL,'P53342B')
INSERT INTO test1 VALUES ( 2,'Smith Close','birmingham North','P53342')

使用这些行我将寻找结果:

1   Winchester Road,    crawley estate, P21869A
2   Smith Close,    birmingham North East,  P53342B

编辑:上面的结果需要在一个表中,而不仅仅是一个逗号分隔的字符串

正如您在结果中看到的那样,输出应该是'akey'字段范围内最长的文本列。

我正在尝试提出一个解决方案,每个列上不涉及大量子查询,实际表有32列和超过1300万行。

我这样做的原因是创建一个清理过的表,每行只有一个ID,每个列的结果最好

这是我的第一篇文章,所以如果您需要更多信息,请告诉我,我很高兴听到有关发布我已经破坏的最佳做法!

感谢

本。

2 个答案:

答案 0 :(得分:2)

SELECT A.akey, 
    (
        SELECT TOP 1 T1.text1
        FROM test1 T1
        WHERE T1.akey=A.akey AND LEN(T1.TEXT1) = MAX(LEN(A.text1))
    ) AS TEXT1,
    (
        SELECT TOP 1 T2.text2
        FROM test1 T2
        WHERE T2.akey=A.akey AND LEN(T2.TEXT2) = MAX(LEN(A.text2))
    ) AS TEXT2,
    (
        SELECT TOP 1 T3.text3
        FROM test1 T3
        WHERE T3.akey=A.akey AND LEN(T3.TEXT3) = MAX(LEN(A.text3))
    ) AS TEXT3
FROM TEST1 AS A
GROUP BY A.akey

我刚刚意识到你说你有32列。我没有看到一个好方法,除非UNPIVOT允许你为每个文本*列创建单独的行(akey,textn)。

编辑:我今天可能没有机会完成这项工作,但UNPIVOT看起来很有用:

;
WITH COLUMNS AS
(
    SELECT akey, [Column], ColumnValue
    FROM
        (
            SELECT X.Akey, X.Text1, X.Text2, X.Text3
            FROM test1 X
        ) AS p
    UNPIVOT (ColumnValue FOR [Column] IN (Text1, Text2, Text3))
    AS UNPVT
)
SELECT *
FROM COLUMNS
ORDER BY akey,[Column], LEN(ColumnValue)

答案 1 :(得分:1)

这看起来真的很难看,但至少有效(在SQL2K上)并且不需要子查询:

select test1.akey, A.text1, B.text2, C.text3
from test1
inner join test1 A on A.akey = test1.akey 
inner join test1 B on B.akey = test1.akey 
inner join test1 C on C.akey = test1.akey 
group by test1.akey, A.text1, B.text2, C.text3
having len(a.text1) = max(len(test1.text1))
   and len(B.text2) = max(len(test1.text2))
   and len(C.text3) = max(len(test1.text3))
order by test1.akey

我必须承认它需要每列的内部联接,我想知道这会如何影响32列x 13百万记录表...我尝试这种方法和一个基于一个子查询并查看执行计划:我真的很想知道