我有大量的非冗余ID和序列,如下所示(表A)。
在第二张表中,我具有要更改的ID,位置和字母的多条记录(表B)。
我想做的就是根据表B中给出的更改替换表A主序列中特定位置的特定字母。
我正在尝试使用STUFF()
函数-下面提供了我的查询示例-但理想情况下,我希望对ProteinID P12111
进行全部4次更改在主序列中同时进行。
SELECT
A.[proteinID],
STUFF(A.[proteinSeq], CAST(B.[position] AS INT), 1, B.[change_to] ) AS [proteinSeq]
FROM
[dbo].[TableA] A
LEFT OUTER JOIN
[dbo].[TableB] B ON A.proteinID = B.proteinID
通过上述查询,我得到了第二个序列的4倍,一次有一个改变。
我不确定是否可以使用STUFF()
实现请求的输出。另一方面,如果可能的话,我想避免使用CURSOR
。有什么建议吗?
答案 0 :(得分:0)
您可以使用递归CTE。我有点不确定change_from
指的是-您更改该位置的值还是不更改。无论如何,逻辑似乎是:
with bb as (
select b.*,
row_number() over (partition by proteinid order by seq) as seqnum
from b
),
cte as
select a.proteinid, a.seq, 1 as lev
from a
union all
select cte.proteinid, stuff(a.seq, b.position, 1, b.change_to), lev + 1
from cte join
b
on cte.lev = b.seqnum and
cte.proteinid = a.proteinid
)
select cte.*
from (select cte.*,
row_number() over (partition by proteinid order by lev desc) as seqnum
from cte
) cte
where seqnum = 1;
答案 1 :(得分:0)
WITH aa AS (
-- get positions and how many times we need to make changes
SELECT a.*,
row_number() over (partition by a.proteinid order by a.seq) as seqnum
, b.position
from [dbo].[TableA] a
RIGHT OUTER JOIN
[dbo].[Tableb] b on
b.proteinid=a.proteinid
),
cte AS
(
-- Get an anchor
SELECT a.proteinid, a.seq, 1 AS lev
FROM [dbo].[Tablea] a
UNION ALL
-- CAST is needed to match the data types, choose yours as needed
SELECT cte.proteinid, CAST(stuff(cte.seq, b.position, 1, b.changeto) AS VARCHAR(100)), lev + 1
FROM cte
INNER JOIN aa
ON cte.lev = aa.seqnum
AND cte.proteinid = aa.proteinid
INNER JOIN [dbo].[TableB] b
ON cte.proteinid = b.proteinid
AND aa.position=b.position
)
SELECT * FROM cte
-- We filter as only need final change
WHERE cte.lev=
(SELECT MAX(t1.lev) FROM cte AS t1
WHERE t1.proteinid=cte.proteinid)
答案 2 :(得分:0)
您可以使用WHILE
代替CURSOR
。
请找到演示here。