Имя: Пароль:
1C
1С v8
Как написать SQL-запрос
,
0 NickNem
 
20.10.13
21:14
Есть справочник приборы, у прибора реквизит "номер" - текстовый, от 00000 до 99999, уникальный для всех приборов.
Справочник имеет группы, у групп есть ТЧ "Номера" с реквизитами "ОТ" и "ДО"
Соответственно, в них прописываются диапазоны приборов, допустимых в каждой группе.
Т.е в группе А например, указаны диапазоны 00300 - 00800 и 45800 - 45995
В группе Б - 11111 - 12002 и 32444 - 34000, и 00302 - 00302
Каждый прибор с конкретным номером должен лежать в папке, соответствующей его номеру.

Вопрос - можно ли запросом найти все возможные "пересечения" номеров в группах? (последний диапазон в группе Б, например)?
И как написать запрос, который выводит все "несоответствующие" приборы, лежащие в чужих папках?
1 КонецЦикла
 
20.10.13
21:29
Ну типа соединение наверное в котором идет сравнение строк (диапазон и номер группы)
2 mrDSide
 
20.10.13
23:59
(0) используйте в языке запросов 1с следующую конструкцию:

ВЫРАЗИТЬ(Приборы.Номер КАК Число(5)) КАК Номер

тоже самое для тч:
3 КонецЦикла
 
21.10.13
00:03
Строки прекрасно сравниваются
4 mrDSide
 
21.10.13
00:04
ВЫРАЗИТЬ(Приборы.Номера.ОТ КАК Число(5)) КАК ЛеваяГраница,
ВЫРАЗИТЬ(Приборы.Номера.ДО КАК Число(5)) КАК ПраваяГраница,

а дальше просто делайте внутреннее соединение виртуальной таблицы справочника (там где не группы) со справочником (выборкой диапазонов) по условию:

ПО (ВТПриборы.Номер>ВТ_ТЧ_Приборы.ПраваяГраница ИЛИ ВТПриборы.Номер<ВТ_ТЧ_Приборы.ПраваяГраница)

все очень просто, но лучше реквизиту изменить тип (на будущее), если там точно только цифры будут (обработкой перебить номер во временный реквизит, потом поменять код, потом обработкой из временного преобразовать в число и задать новый код), отключить автонумерацию.
5 Sorm
 
21.10.13
00:05
(0) Именно в скуле?
6 mrDSide
 
21.10.13
00:06
(3) Не пишите ерунду, если не читаете внимательно условие.
Как строку проверить на вхождение в диапазон? Можно, конечно, по кодам символов... ИМХО
7 Rie
 
21.10.13
00:07
(4) А зачем в числа-то преобразовывать?

(6) Сравнить с границами диапазона. Точно так же, как и для чисел.
8 Sorm
 
21.10.13
00:08
(6) А в чем беда в строках с лидирующими нулями? Все очень даже запросто.
9 mrDSide
 
21.10.13
00:09
(7) Затем, что Приборы.Номер можно сравнить только на полное совпадение, т.к. это СТРОКИ...
написано же в условии
10 mrDSide
 
21.10.13
00:11
Т.е. Приборы.Номер>"абвгд" будет Ложь, т.к. длина у строк одинаковая. Хотя бог его знает как работают операторы сравнения строк в запросах (кроме "=", само собой).
11 Sorm
 
21.10.13
00:15
(0) Второй запрос будет выглядеть примерно так:
Select
Номер
from
Приборы
inner join
Группы
on
Приборы.Группа = Группы.Код
где
Приборы.Код<Группа.ОТ or Приборы.Код > Группа.ДО
12 Rie
 
21.10.13
00:16
(10) Открой консоль запросов. Введи что-нибудь вроде
ВЫБРАТЬ
ВЫБОР КОГДА "123">"100" ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК А,
ВЫБОР КОГДА "123"<"100"  ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК Б
Посмотри на результат.
13 mrDSide
 
21.10.13
00:29
(12) работает без явного преобразования. Если преобразование в число производит сам компилятор - это хорошо. Тогда остается задать верно связи как в (4) + ПО НЕ Приборы.ЭтоГруппа
14 Rie
 
21.10.13
00:39
(13) Никакого преобразования в число не производится. Строки сравниваются в лексикограческом порядке.
В задаче из (0), поскольку есть лидирующие нули, лексикографического порядка - достаточно.

Можно, к слову, даже так:
Приборы.Номер МЕЖДУ ЛеваяГраница И ПраваяГраница
15 NickNem
 
21.10.13
01:19
Да, вот такое работает нормально (при записи определяет нужную группу)

ВЫБРАТЬ
    Приборы.Ссылка КАК ГруппаПрибора,
    ПриборыНомера.От КАК ОТ,
    ПриборыНомера.До КАК ДО
ИЗ  
    Справочник.Приборы.Номера КАК ПриборыНомера
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Приборы КАК Приборы
    ПО Приборы.Ссылка = ПриборыНомера.Ссылка
    И Приборы.ЭтоГруппа
ГДЕ &НомерПрибора МЕЖДУ ОТ И ДО
16 NickNem
 
21.10.13
01:24
Никак только не могу ухватить, как построить запрос, чтобы получить приборы с "неправильными" группами :-(
17 Rie
 
21.10.13
01:34
(16) Что-то вроде
ВЫБРАТЬ
    Приборы.Ссылка
ИЗ
    Справочник.Приборы КАК Приборы
    СОЕДИНЕНИЕ Справочник.Приборы.Номера КАК ПриборыНомера
        ПО Приборы.Родитель = ПриборыНомера.Ссылка
        И НЕ Приборы.ЭтоГруппа
        М Приборы.Номер МЕЖДУ ПриборыНомера.От И ПриборыНомера.До
СГРУППИРОВАТЬ ПО Приборы.Ссылка
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(ПриборыНомера)=0
18 КонецЦикла
 
21.10.13
01:36
(9) где '00032' > '00030' и '00032' < '00040'
...или мы о разном?
19 NickNem
 
21.10.13
02:47
(17) Спасибо, Rie, мысль ухватил, сначала все-таки не получалось, но немного переделал и вроде как получилось:

      ПО (Приборы.Родитель = ПриборыНомера.Ссылка
         ИЛИ Приборы.Номер МЕЖДУ ПриборыНомера.От И ПриборыНомера.До)
      И НЕ Приборы.ЭтоГруппа
СГРУППИРОВАТЬ ПО Приборы.Ссылка
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПриборыНомера.Ссылка)>1

Вроде то что надо.
Правда выдает некоторые лишние, но выдает "законно" - там есть пересечения номеров внутри одной группы.
20 NickNem
 
21.10.13
02:50
А вот с фильтрацией пересечений номеров (теперь еще и внутри групп) пока ничего...
21 Rie
 
21.10.13
02:56
(20) Что-нибудь вроде
ВЫБРАТЬ
   ПриборыНомера1.Ссылка КАК Группа1
,  ПриборыНомера2.Ссылка КАК Группа2
ИЗ
   Справочник.Приборы.Номера КАК ПриборыНомера1
,  Справочник.Приборы.Номера КАК ПриборыНомера2
ГДЕ
   ПриборыНомера1.Ссылка<>ПриборыНомера2.Ссылка
   И (ПриборыНомера1.От МЕЖДУ ПриборыНомера2.От И ПриборыНомера2.До
      ИЛИ ПриборыНомера1.До МЕЖДУ ПриборыНомера2.От И ПриборыНомера2.До
      ИЛИ ПриборыНомера2.От МЕЖДУ ПриборыНомера1.От И ПриборыНомера1.До
      ИЛИ ПриборыНомера2.До МЕЖДУ ПриборыНомера1.От И ПриборыНомера1.До)
22 NickNem
 
21.10.13
03:15
Да, просто, как все гениальное...
Rie, снимаю шляпу, вы просто гений - два удара - восемь дыр :-)
Спасибо.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой