Hy,请帮忙,我有12个项目的完整序列,我通过2个不同的组(12345和54321)识别这些项目。现在,我需要确定项目“12345”的第一个序列在4处停止并在10处重新开始。这样的事情:
我有这张桌子:
------------------
|seq |partNumber|
------------------
| 1 | 12345 |
| 2 | 12345 |
| 3 | 12345 |
| 4 | 12345 |
| 10 | 12345 |
| 11 | 12345 |
| 12 | 12345 |
| 5 | 54321 |
| 6 | 54321 |
| 7 | 54321 |
| 8 | 54321 |
| 9 | 54321 |
------------------
我需要找到这个结果:
------------
|Start|Stop|
------------
| 5 | 9 | (partnumber:12345)
------------
我使用的查询:
select start, stop from (
select m.partNumber + 1 as start,
(select min(partNumber) - 1 from seq as x where x.partNumber > m.partNumber) as stop
from seq as m
left outer join seq as r on m.partNumber = r.partNumber - 1 where r.partNumber is null) as x
where stop is not null;
但是,这个查询给了我这个结果:
------------
|Start|Stop|
------------
| 9 | 9 | (partnumber:12345)
------------
最终结果: 我想确定序列中的“12345”开始于1个结束,4个(休息)重启,10个结束12,我有一个5到9的间隙。“54321”的另一个序列从5个结束开始,9,这里我不要没有差距。
答案 0 :(得分:0)
这是结构化查询语言的结构化部分的一个很好的应用程序。
我猜你永远不会有seq
小于零或大于仲裁值15624
的值。这个猜测很重要:我们需要一个包含该范围内所有基数的表来使缺失数检测起作用。
这是一张表
SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F
(如果您使用的是MariaDB,则可以使用Sequence表seq_0_to_15624
代替这一部分SQL代码。)
接下来,您需要一种方法来找出每个部件号的seq
的最低值和最高值。你是这样做的。
SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq
FROM seq
GROUP BY partNumber
接下来,您需要生成一个表格,显示每个部件编号从最小到最大的所有可能序列号:
SELECT cardinals.seq, r.partNumber
FROM (
SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F
) cardinals
JOIN (
SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq
FROM seq
GROUP BY partNumber
) r ON cardinals.seq >= r.minSeq AND cardinals.seq <= r.maxSeq
最后,您可以将其连接到原始表格,然后WHERE val IS NULL
找到您丢失的序列号。
SELECT cardinals.seq, r.partNumber
FROM (
SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E
JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F
) cardinals
JOIN (
SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq
FROM seq
GROUP BY partNumber
) r ON cardinals.seq >= r.minSeq AND cardinals.seq <= r.maxSeq
LEFT JOIN seq ON cardinals.seq = seq.seq AND r.PartNumber = seq.partNumber
WHERE seq.seq IS NULL