Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于连接和删除公共前缀的TSQL查询_Sql_Sql Server_Tsql - Fatal编程技术网

用于连接和删除公共前缀的TSQL查询

用于连接和删除公共前缀的TSQL查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一些数据 id ref == ========== 1 3536757616 1 3536757617 1 3536757618 并且想要得到结果 1 3536757616/7/8 2 3536757629/28/30 因此,基本上数据是在id上聚合的,引用连接在一起,用斜杠“/”分隔,但删除了任何公共前缀,因此如果数据是 id ref == ========== 2 3536757628 2 3536757629 2

我有一些数据

id    ref
==   ==========
1    3536757616
1    3536757617
1    3536757618
并且想要得到结果

1    3536757616/7/8
2    3536757629/28/30
因此,基本上数据是在id上聚合的,引用连接在一起,用斜杠“/”分隔,但删除了任何公共前缀,因此如果数据是

id    ref
==   ==========
2    3536757628
2    3536757629
2    3536757630
我想知道结果

1    3536757616/7/8
2    3536757629/28/30
我知道我可以通过使用

SELECT distinct
    id,
    stuff ( ( SELECT
                  '/ ' + ref 
              FROM
                  tableA tableA_1
              where tableA_1.id = tableA_2.id
    FOR XML PATH ( '' ) ) , 1 , 2 , '' )
from TableA tableA_2
给予

1   3536757616/ 3536757617/ 3536757618
2   3536757628/ 3536757629/ 3536757630
但正是这一点消除了我所追求的共同元素

测试数据代码:

create table tableA (id int, ref varchar(50))

insert into tableA
select 1, 3536757616
union select 1, 3536757617
union select 1, 3536757618
union select 2, 3536757628
union select 2, 3536757629
union select 2, 3536757630

我将我的表命名为T,并使用以下SELECT语句

select id, number, substring(#t.ref, 1, v.number), count(id)
from master.dbo.spt_values v
inner join #t on v.number <= len(#t.ref)
where v.name is null and v.number > 0 
group by id, number, substring(#t.ref, 1, v.number)
order by id, count(id) desc, number desc
您将得到一个结果集,其中每个id的第一条记录包含每个id的最大长度和最长初始字符串

这不是一个完整的解决方案,而是一个很好的起点:迭代id,发出SELECT TOP 1以检索最长的字符串,并连接具有相同id的每个记录的字符串差异

WITH hier(cnt) AS
        (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt <= 100
        )
SELECT  CASE WHEN ROW_NUMBER() OVER (ORDER BY id) = 1 THEN ref ELSE ' / ' + SUBSTRING(ref, mc + 1, LEN(ref)) END 
FROM    (
        SELECT  MIN(common) AS mc
        FROM    (
                SELECT  (
                        SELECT  MAX(cnt)
                        FROM    hier
                        WHERE   SUBSTRING(initref, 1, cnt) = SUBSTRING(ref, 1, cnt)
                                AND cnt <= LEN(ref)
                        ) AS common
                FROM    (
                        SELECT  TOP 1 ref AS initref
                        FROM    tableA
                        ) i,
                        tableA
                ) q
        ) q2, tableA
FOR XML PATH('')

---

3536757616 / 17 / 18 / 28 / 29 / 30
团体也是如此:

WITH hier(cnt) AS
        (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt <= 100
        )
SELECT  (
        SELECT  CASE WHEN ROW_NUMBER() OVER (ORDER BY a2.ref) = 1 THEN ref ELSE ' / ' + SUBSTRING(ref, mc + 1, LEN(ref)) END 
        FROM    tableA a2
        WHERE   a2.id = q2.id
        FOR XML PATH('')
        )
FROM    (
        SELECT  id, MIN(common) AS mc
        FROM    (
                SELECT  a.id,
                        (
                        SELECT  MAX(cnt)
                        FROM    hier
                        WHERE   SUBSTRING(i.initref, 1, cnt) = SUBSTRING(a.ref, 1, cnt)
                                AND cnt <= LEN(ref)
                        ) AS common
                FROM    (
                        SELECT  id, MIN(ref) AS initref
                        FROM    tableA
                        GROUP BY
                                id
                        ) i
                JOIN    tableA a
                ON      i.id = a.id
                ) q
        GROUP BY
                id
        ) q2
---
3536757616 / 7 / 8
3536757628 / 29 / 30

+1.我想用大脑来思考这个问题,但这确实是一个很好的方法。远远超过目前的其他两个答案,包括我自己的。@Lieven:将成为我博客中明天帖子的主题只要在最终选择中添加id,它就完美了!