كيفية العثور على القيمة المفقودة في التسلسل داخل المجموعات في SQL؟

StackOverflow https://stackoverflow.com/questions/727392

  •  05-09-2019
  •  | 
  •  

سؤال

لدي جدول من المعرفات والمواقف

CREATE TABLE #MissingSequence (ID INT NOT NULL, Position INT NOT NULL)
INSERT INTO #MissingSequence (ID,Position)
SELECT 36,1
UNION ALL SELECT 36,2
UNION ALL SELECT 36,3
UNION ALL SELECT 36,4
UNION ALL SELECT 36,5
UNION ALL SELECT 36,6
UNION ALL SELECT 44,1
UNION ALL SELECT 44,3
UNION ALL SELECT 44,4
UNION ALL SELECT 44,5
UNION ALL SELECT 44,6

ما أحاول العثور عليه هو إذا كان هناك أي استراحة في تسلسل المواقف حسب المعرف في هذه الحالة، فإن الاستراحة بين 44،1 و 44،3

لقد تمكنت من تحليل معا:

SELECT  l.ID
    ,Start_Position = MIN(l.Position) + 1
    ,Stop_Position = MIN(fr.Position) - 1
FROM #MissingSequence l
LEFT JOIN #MissingSequence r 
    ON l.Position = r.Position - 1
LEFT JOIN #MissingSequence fr 
    ON l.Position < fr.Position
WHERE r.Position IS NULL
    AND fr.Position IS NOT NULL
GROUP BY l.ID

لكنه لا يعمل إذا كان هناك قيم معرف متعددة. إنه يعمل إذا كان معرف واحد فقط، 44 موجودا.

الأفكار، والتعليقات، والاقتراحات؟

شكرا!

هل كانت مفيدة؟

المحلول

كان الانضمام الذاتي الأيسر غريزة جيدة، لكنني لا أعتقد أن المجاميع ستقطعها، وبالتأكيد تحتاج إلى تضمين جملة المعرف المطابقة في نظامك الذاتي.

إليك إصدار (ANSI

SELECT
    above.ID AS ID, below.Position+1 AS Start_Position, above.Position-1 AS End_Position
FROM MissingSequence AS above
JOIN MissingSequence AS below
    ON below.ID=above.ID AND below.Position<above.Position-1
LEFT JOIN MissingSequence AS inbetween
    ON inbetween.ID=below.ID AND inbetween.Position BETWEEN below.Position+1 AND above.Position-1
WHERE inbetween.ID IS NULL;

+----+----------------+--------------+
| ID | Start_Position | End_Position |
+----+----------------+--------------+
| 44 |              2 |            2 | 
+----+----------------+--------------+

نصائح أخرى

هذا الاستعلام يبقع الزلات، ونأمل أن تكون مفيدة؛ إذا كنت في SQL 2005، يمكنك استخدام CTE

SELECT ID, Position + 1
FROM #MissingSequence t1
WHERE (Position + 1) NOT IN (SELECT Position FROM #MissingSequence t2 WHERE t1.ID = t2.ID)
AND Position <> (SELECT MAX(Position) FROM #MissingSequence t2 WHERE t1.ID = t2.ID)
create database testing
use testing;
create table sequence (
    id int not null primary key
);

insert into sequence(id) values
    (1), (2), (3), (4), (6), (7), (8), (9),
    (10), (15), (16), (17), (18), (19), (20);

select * from sequence

Create PROCEDURE test_proce(@mode varchar(50))   
AS
BEGIN
    declare @se int;
    set @se=0;
    set @se=(
        select top 1 t.id + 1 
        from sequence t 
        left join sequence x on x.id = t.id + 1 
        where x.id is null 
        order by t.id
    );
    select * from sequence where id<@se;
END

exec test_proce 'mode'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top