【问题标题】:How to extract multiple rows from a table based on values from multiple columns from another table and then concatenate in SQL?如何根据另一个表中多个列的值从一个表中提取多行,然后在 SQL 中连接?
【发布时间】:2021-01-21 23:01:14
【问题描述】:

我有两个表,表 1 和表 2。表 1 有 "start" 和 "end" 列。表 2 具有列“位置”和“序列”。我想从表 2 中提取从 position = start 到 position = end 的序列,并使用连接的字符串创建一个新列。

表 1

Start End
100 104
105 109

表 2

Position Seq
100 A
101 T
102 C
103 T
104 G
105 T
106 T
107 G
108 T
109 G

我的最终结果需要是

Start End Sequence
100 104 ATCTG
105 109 TTGTG

我尝试使用以下语句连接表 2 中的值

 SELECT Sequence = (Select '' + Seq 
 from Table2
 where Position >= 100 and Position <= 104
 order by Position FOR XML PATH('')

)

【问题讨论】:

  • 您使用的是什么 DBMS 以及哪个版本?
  • 我使用的是 SQL Server 2016。

标签: sql merge concatenation


【解决方案1】:

您没有说明您使用的是什么 DBMS,所以这里是一个使用 CTE 和 FOR XML 执行转置的 SQL Server 解决方案:

; WITH SequenceCTE AS
(
    SELECT  [Start],
            [End],
            Seq
    FROM    Table1 a
            JOIN Table2 b
                ON b.Position >= a.[Start] AND
                  b.Position <= a.[End]
)
SELECT  DISTINCT
        a.[Start],
        a.[End],
        (
            SELECT  STUFF(',' + Seq,1,1,'')
            FROM    SequenceCTE b
            WHERE   a.[Start] = b.[Start] AND
                    a.[End] = b.[end]
            FOR XML PATH ('') 
        )
FROM    SequenceCTE a

【讨论】:

    【解决方案2】:

    在标准 SQL 中,您可以执行以下操作:

    select t1.start, t1.end,
           listagg(t2.position, '') within group (order by t2.seq) as sequence
    from table1 t1 join
         table2 t2
         on t2.position between t1.start and t2.end
    group by t1.start, t1.end;
    

    大多数数据库支持聚合字符串连接,但函数可能有不同的名称和略有不同的语法。

    请注意,startend 是不好的列名称,因为它们是 SQL 关键字 - 大多数数据库中的 sequence 也是如此。

    【讨论】:

      【解决方案3】:

      您可以为您的第一个表生成行号,这些行号稍后可用于在加入这些数字后对范围进行分组:

      with to_id as (select row_number(*) over (order by t1.start) id, t1.* from table1 t1), 
           ranges as (select t3.id, t2.* from table2 t2 join to_id t3 on t3.start <= t2.position and t2.position <= t3.end)
      select t3.start, t3.end, group_concat(r1.seq, '') from ranges r1 join to_id t3 on r1.id = t3.id group by r1.id;
      

      【讨论】:

        【解决方案4】:

        查看交叉表查询是如何完成的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-29
          • 1970-01-01
          • 2015-05-03
          • 1970-01-01
          • 1970-01-01
          • 2016-01-13
          相关资源
          最近更新 更多