我有一些这样的数据(download 10,000 rows of sample data here):
id parent sequence mz1_monoisotopic
---------------------------------------
1 0 SGVNHR 669.34
2 0 IEEIATDLK 1030.99
3 0 AMDAWGAS 1030.07
5 1 MDLILDDR 990.49
7 1 AAAGGGAG 1029.50
8 1 LEVSEELIEK 1188.64
我需要对其执行一系列步骤,但我不确定如何构建我的查询。以下是步骤:
展开这个表格。查看 sequence
,并计算每个序列中 M
的数量。对于序列中的每个 M
,创建一个新条目,其中 mz1_monoisotopic
的值增加 16。我使用递归公用表表达式实现了这一点(在底部查看代码)
id parent sequence mz1_monoisotopic <--- THIS IS THE EXPANDED TABLE
---------------------------------------
1 0 SGVNHR 1006.34
2 0 IEEIATDLK 1030.99
3 0 AMDAWGAS 1030.07
4 0 AMDAWGAS 1046.07 <--- NEW ROW! mz1_monoisotopic increased by 16.
5 1 MDLILDDR 990.49
6 1 MDLILDDR 1006.49 <--- NEW ROW, mz1_monoisotopic increased by 16.
7 1 AAAGGGAG 1029.50
8 1 LEVSEELIEK 1188.64
使用用户定义的值列表(长度可变)——比如说 [1006, 1030, 1351 ...]
,搜索这个新的扩展表(从步骤 1 开始)并找到 {{1 }} 在每个值 (mz1_monoisotopic
) 的 1 个单位内。每个值可以匹配多个 WHERE mz1_monoisotopic BETWEEN value - 1 AND value + 1
,但只能返回一个匹配 PER parents
。因此,值 parent
在第 2、3 和 7 行的 1 个单位内。其中两个来自 1030
,因此它必须选择误差最低的一个。其中之一来自 parent == 0
1,因此它可以保留它。一些预期的输出:
parent
将每个单独查询的结果合并到一个表中
#RESULT FROM QUERYING WITH 1006:
id parent sequence mz1_monoisotopic
---------------------------------------
1 0 SGVNHR 1006.34
6 1 MDLILDDR 1006.49
#RESULT FROM QUERYING WITH 1030:
id parent sequence mz1_monoisotopic
---------------------------------------
3 0 AMDAWGAS 1030.07
7 1 AAAGGGAG 1029.50
...
我不知道从哪里开始,如果我想像数组一样单独查询数字列表,正如我所提到的。我需要帮助将这些转换为更大的单一查询。这是我第 1 步的 CTE:
id parent sequence mz1_monoisotopic
---------------------------------------
1 0 SGVNHR 1006.34
3 0 AMDAWGAS 1030.07
6 1 MDLILDDR 1006.49
7 1 AAAGGGAG 1029.50
这是选择错误最少的行的查询,按WITH RECURSIVE
cte (id, parent, sequence, mz1_monoisotopic, missed_cleavages, MSO) AS
(
SELECT
id,
parent,
sequence,
(mz1_monoisotopic
+ ((CHAR_LENGTH(sequence) - CHAR_LENGTH(REPLACE( sequence, 'C', ''))) * 57)
# More fixed mods
) as mz1_monoisotopic,
missed_cleavages,
0 AS MSO
FROM
`1_plant_trypsin_dig`
UNION ALL
SELECT
id,
parent,
sequence,
`mz1_monoisotopic` + 15.999 AS `mz1_monoisotopic`,
missed_cleavages,
MSO + 1
FROM
cte
WHERE
MSO < (CHAR_LENGTH(sequence) - CHAR_LENGTH(REPLACE( sequence, 'M', '')))
)
分组:
parent
答案 0 :(得分:1)
好的,所以我不会详细介绍与扩展表格有关的任何细节,因为您似乎自己正确地管理了这一点。
第二个问题可以用一个搜索表和一个分区的 ROW_NUMBER()
来解决。
当我们假设以下基表设置时:
CREATE TABLE 1_plant_trypsin_dig (
id INT,
parent INT,
sequence VARCHAR(50),
mz1_monoisotopic DECIMAL(10,2)
);
INSERT INTO 1_plant_trypsin_dig VALUES (1, 0, 'SGVNHR', 1006.34);
INSERT INTO 1_plant_trypsin_dig VALUES (2, 0, 'IEEIATDLK', 1030.99);
INSERT INTO 1_plant_trypsin_dig VALUES (3, 0, 'AMDAWGAS', 1030.07);
INSERT INTO 1_plant_trypsin_dig VALUES (4, 0, 'AMDAWGAS', 1046.07);
INSERT INTO 1_plant_trypsin_dig VALUES (5, 1, 'MDLILDDR', 990.49);
INSERT INTO 1_plant_trypsin_dig VALUES (6, 1, 'MDLILDDR', 1006.49);
INSERT INTO 1_plant_trypsin_dig VALUES (7, 1, 'AAAGGGAG', 1029.50);
INSERT INTO 1_plant_trypsin_dig VALUES (8, 1, 'LEVSEELIEK', 1188.64);
和这样的搜索表(这可能是一个特定于连接的临时表,以支持多用户场景):
CREATE TABLE search (
mz1_monoisotopic DECIMAL(10,2)
);
INSERT INTO search VALUES (1006.00);
INSERT INTO search VALUES (1030.00);
那么 - 假设我们将“错误”定义为实际 mz1_monoisotopic
和搜索到的 mz1_monoisotopic
之间的绝对差异 - 我们可以这样做:
SELECT id, parent, sequence, mz1_monoisotopic, err FROM (
SELECT
d.id,
d.parent,
d.sequence,
d.mz1_monoisotopic,
ABS(d.mz1_monoisotopic - s.mz1_monoisotopic) err,
ROW_NUMBER() over (
PARTITION BY s.mz1_monoisotopic, d.parent
ORDER BY ABS(d.mz1_monoisotopic - s.mz1_monoisotopic), id
) rn
FROM
1_plant_trypsin_dig d
INNER JOIN search s ON
d.mz1_monoisotopic BETWEEN s.mz1_monoisotopic - 1 AND s.mz1_monoisotopic + 1
) result WHERE rn = 1;
并收到此结果:
id parent sequence mz1_monoisotopic err 1 0 SGVNHR 1006.34 0.34 6 1 MDLILDDR 1006.49 0.49 3 0 AMDAWGAS 1030.07 0.07 7 1 AAAGGGAG 1029.50 0.50
请记住,您需要为 ROW_NUMBER()
订单定义决胜局,以防两行具有相同的错误值。我用过 id
,您的偏好可能会有所不同。
请参阅 https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=75738999738d10b03e43fb768267eefc
的现场示例