Извините, длинная предыстория, но нужно уточнить вопрос.
В моей организации у компьютеров есть имена вроде CNT30[0-9]{3}[1-9a-z]
, например cnt300021
или cnt30253a
.
Последний символ является «классификатором», поэтому одному рабочему месту могут быть присвоены компьютеры с одинаковыми именами, различаемые этим классификатором. Например, cnt300021
может означать настольный компьютер на рабочем месте # 002, а cnt30002a
может означать ноутбук, назначенный для того же рабочего места. Рабочие места являются «виртуальными», и их существование создано исключительно для нашего удобства (ИТ-отдел).
Каждый отдел имеет свой уникальный диапазон [0-9]{3}
. Например, компьютеры учета имеют имена, начинающиеся с cnt302751
до cnt30299z
, что дает им максимум 25 уникальных рабочих мест, до 35 компьютеров на одно рабочее место. (Большинство пользователей IRL имеют один настольный ПК, гораздо меньше - настольный компьютер и ноутбук, и только 2 или 3 технических специалиста имеют в своем распоряжении более одного ноутбука).
Недавно, проводя инвентаризацию паспортов компьютеров (не уверен насчет термина: бумага, которая означает для компьютера то же самое, что означает паспорт для человека), Я обнаружил, что в последовательных дырах есть некоторые дыры нумерация. Например, у нас есть cnt302531
и cnt302551
, но нет cnt302541
, что означает, что нет рабочего места # 254.
Что я хочу сделать? Я хочу найти эти пробелы без ручного поиска. Для этого мне нужен цикл от 1 до MaxComp=664
(больше рабочих мест не назначено)
Вот что я мог бы написать, используя псевдо-SQL-Бейсик:
for a=0 to MaxComp
a$="CNT30"+right(a+1000,3)
'comparing only 8 leftmost characters, ignoring 9th one - the qualifier
b$=(select name from table where left(name,8) like a$)
print a$;b$
next a
Этот код должен дать мне два столбца: возможные имена и существующие.
Но я не могу понять, как реализовать это в SQL-запросе. Что я пробовал:
# because of qualifier there may be several computers with same
# 8 leftmost characters
select @cnum:=@cnum+1 as CompNum, group_concat(name separator ',')
# PCs are inventoried by OCS-NG Inventory software
from hardware
cross join (select @cnum:=0) cnt
where left(hardware.name,8)=concat('CNT30',right(@cnum+1000,3))
limit 100
Но эта конструкция возвращает ровно одну строку. И я не могу понять, если это возможно без использования хранимых процедур, и что я сделал не так, если это возможно?