我在一個SQL表以下數據:SQL查詢找到失蹤的連續編號
我需要查詢的數據,所以我可以得到失蹤名單每名員工「FAMILYID」。
舉例來說,我應該得到員工1021缺少序列中的ID:2和5以及爲職工1027應該得到丟失號碼1和6
關於如何查詢任何線索?
感謝任何幫助。
我在一個SQL表以下數據:SQL查詢找到失蹤的連續編號
我需要查詢的數據,所以我可以得到失蹤名單每名員工「FAMILYID」。
舉例來說,我應該得到員工1021缺少序列中的ID:2和5以及爲職工1027應該得到丟失號碼1和6
關於如何查詢任何線索?
感謝任何幫助。
找到的第一個缺失值
我將使用ROW_NUMBER
window function來分配「正確的」序列ID號碼。假設序列ID重新開始,每次員工ID的變化:
SELECT
e.id,
e.name,
e.employee_number,
e.relation,
e.familyid,
ROW_NUMBER() OVER(PARTITION BY e.employeeid ORDER BY familyid) - 1 AS sequenceid
FROM employee_members e
然後,我會篩選結果設置爲只包括與錯配序列ID的行:
SELECT *
FROM (
SELECT
e.id,
e.name,
e.employee_number,
e.relation,
e.familyid,
ROW_NUMBER() OVER(PARTITION BY e.employeeid ORDER BY familyid) - 1 AS sequenceid
FROM employee_members e
) a
WHERE a.familyid <> a.sequenceid
話又說回來,你應該容易被employee_number
組,並找到爲每個員工第一丟失的序列ID:
SELECT
a.employee_number,
MIN(a.sequence_id) AS first_missing
FROM (
SELECT
e.id,
e.name,
e.employee_number,
e.relation,
e.familyid,
ROW_NUMBER() OVER(PARTITION BY e.employeeid ORDER BY familyid) - 1 AS sequenceid
FROM employee_members e
) a
WHERE a.familyid <> a.sequenceid
GROUP BY a.employee_number
找到所有失蹤VALU ES
擴展前面的查詢,我們每次都能檢測到缺少值之差familyid
和sequenceid
變化之間:
-- Warning: this is totally untested :-/
SELECT
b.employee_number,
MIN(b.sequence_id) AS missing
FROM (
SELECT
a.*,
a.familyid - a.sequenceid AS displacement
SELECT
e.*,
ROW_NUMBER() OVER(PARTITION BY e.employeeid ORDER BY familyid) - 1 AS sequenceid
FROM employee_members e
) a
) b
WHERE b.displacement <> 0
GROUP BY
b.employee_number,
b.displacement
這將起作用,您選擇所有「依賴者」,並在前一行中加入左連接。如果該行不存在,那麼你顯示結果:
SELECT 'Missing Prior', t1.*
FROM employee_members t1
LEFT JOIN employee_members t2 ON t1.employee_number = t2.employee_number
AND (t1.familyid-1) = t2.familyid
WHERE t2.employee_number is null and t1.relation == 'Dependent'
另一個版本,顯示你丟失的數量:
SELECT t1.employee_number, t1.familyid-1 as Missing_Member
FROM employee_members t1
LEFT JOIN employee_members t2 ON t1.employee_number = t2.employee_number
AND (t1.familyid-1) = t2.familyid
WHERE t2.employee_number is null and t1.relation == 'Dependent'
這是一種方法。計算每位員工的最大家庭標識。然後將其加入到最大家庭編號的數字列表中。結果對於每個員工和預期的家庭標識都有一行。
做一個left outer join
從這回到原始數據,在familyid
和數字。凡沒有匹配項,這些都是缺失值:
with nums as (
select 1 as n
union all
select n+1
from nums
where n < 20
)
select en.employee, n.n as MissingFamilyId
from (select employee, min(familyid) as minfi, max(familyid) as maxfi
from t
group by employee
) en join
nums n
on n.n <= maxfi left outer join
t
on t.employee = en.employee and
t.familyid = n.n
where t.employee_number is null;
注意,當缺少familyid
是序列中的最後一個數字,這將不起作用。但它可能是你可以用你的數據結構做的最好的。
另外,上述查詢假定最多有20個家庭成員。
此選擇將使用CTE方法檢索每位員工缺失的「familyid」列表。
QUERY:
WITH emp_grp (
EmployeeID
,MaxFamilyID
)
AS (
SELECT e2.EmployeeID
,MAX(e2.FamilyID) MaxFamilyID
FROM employee_number e2
GROUP BY e2.EmployeeID
)
,emp_mem
AS (
SELECT EmployeeID
,0 AS FamilyID
,MaxFamilyID
FROM emp_grp
UNION ALL
SELECT EmployeeID
,FamilyID + 1 AS FamilyID
,MaxFamilyID
FROM emp_mem
WHERE emp_mem.FamilyID < MaxFamilyID
)
SELECT emp_mem.EmployeeID
,emp_mem.FamilyID
FROM emp_mem
LEFT JOIN employee_number emp_num ON emp_mem.EmployeeID = emp_num.EmployeeID
AND emp_mem.FamilyID = emp_num.FamilyID
WHERE emp_num.EmployeeID IS NULL
ORDER BY emp_mem.EmployeeID
,emp_mem.FamilyID
OPTION (MAXRECURSION 32767)
OUTPUT:
EmployeeID FamilyID
----------- -----------
1021 2
1021 5
1027 1
1027 6
另一種解決方案: 建立了從序列的所有可能值的表(可以用這個身份出戰)。然後在源表爲空的表上留下加入。
DECLARE @Seq TABLE (id INT IDENTITY(1, 1))
DECLARE @iter INT = 1
WHILE @iter <= (
SELECT MAX([your ID column])
FROM [Offending Table]
)
BEGIN
INSERT @Seq DEFAULT
VALUES
SET @iter = @iter + 1
END
SELECT id
FROM @seq s
LEFT JOIN [Offending Table] ot ON s.id = ot.[your ID column]
WHERE ot.[Offending Table]IS NULL
我們無法看到完整的列名 – Hogan
最後一列名稱是「familyid」。 – VAAA
和第三列和表名? – Hogan