Записи без подчинённых

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Записи без подчинённых

Сообщение Alexanbar » 04.11.2005 (Пт) 3:13

Access-97. Есть запрос, который работает:
SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM Packs LEFT JOIN Projects ON (Packs.ObjType = Projects.ObjType) AND (Packs.N = Projects.[Obj ID])
WHERE (((Projects.[Obj ID]) Is Null));


Но для того, чтобы он работал, пришлось в таблицу Packs ввести фиктивное поле ObjType, которое всегда равно 1, а это не есть хорошо. Как бы обойтись прежним форматом таблицы Packs, и не вводить фиктивное поле?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 3:20

Спать хочу, поэтому не знаю, но может

Код: Выделить всё
SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM Packs LEFT JOIN Projects ON Packs.N = Projects.[Obj ID]
WHERE Projects.[Obj ID] Is Null AND Projects.ObjType = 1;
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 04.11.2005 (Пт) 12:03

Код: Выделить всё
SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM Packs
  LEFT JOIN Projects ON (Packs.N = Projects.[Obj ID])
    AND (Projects.ObjType = 1)
WHERE (Projects.[Obj ID] Is Null);

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 12:32

А Access схавает джойн на константу? :roll:
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 12:32

Это уже пробовалось:

Ennor писал(а):
Код: Выделить всё
SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM Packs
  LEFT JOIN Projects ON (Packs.N = Projects.[Obj ID])
    AND (Projects.ObjType = 1)
WHERE (Projects.[Obj ID] Is Null);


На это получаю сообщение:
Join expression not supported


А это, к сожалению,
SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM Packs LEFT JOIN Projects ON Packs.N = Projects.[Obj ID]
WHERE Projects.[Obj ID] IS NULL AND Projects.ObjType = 1;


возвращает неверный результат.


Можно, конечно, попробовать создать запрос, в котором перечислить все поля из Packs и добавить константу
1 as ObjType
, а затем сослаться на него в новом запросе вместо таблицы Packs.

Вот если бы можно было бы записать подряд несколько sQL предложений, и в первом ввести обозначения:

{SElect Packs.[N],..... , 1 as ObjType} as Packs1; SElect Packs1.[N]....,Projects.Obj From ....;

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 12:34

Легко, просто два отдельных запроса сделай, и вызови первый из второго.


А если словами - что должен вернуть запрос?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 12:52

GSerg писал(а):Легко, просто два отдельных запроса сделай, и вызови первый из второго.


А если словами - что должен вернуть запрос?


Вернуть те записи из Packs, у которых нет соответствующих в Projects. Сопоставление идёт так: Packs.N=Projects.[Obj ID], но при этом Projects.ObjType должен быть равен 1. Те записи, для которых Packs.N=Projects.[Obj ID] и Projects.ObjType=0 учитываться не должны (ObjType=0 используется для сопоставления с совсем другой таблицей).

Попробовал создать отдельный запрос на добавление фиктивного поля 1 as ObjType к таблице Packs.

SELECT Packs.N, Packs.Name, Packs.Deleted, Packs.Comments, 1 AS ObjType
FROM Packs;



Если на него сослаться как на источник во втором запросе:

SELECT [Packs&ObjType].N, [Packs&ObjType].Name, [Packs&ObjType].Deleted, [Packs&ObjType].Comments, [Packs&ObjType].ObjType, Projects.Project, Projects.InsArcPrj, Projects.[Obj ID]
FROM [Packs&ObjType] LEFT JOIN Projects ON ([Packs&ObjType].ObjType = Projects.ObjType) AND ([Packs&ObjType].N = Projects.[Obj ID])
WHERE (((Projects.[Obj ID]) Is Null));


результат, почему-то опять неверный (ни одной записи).

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 04.11.2005 (Пт) 13:13

Alexanbar писал(а):На это получаю сообщение:
Join expression not supported

См. здесь: "Access :: LEFT JOIN с константой"

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 13:16

Код: Выделить всё
SELECT *
FROM Packs
WHERE Packs.RowID NOT IN (SELECT RowID FROM Packs INNER JOIN Projects ON Packs.N=Projects.[Obj ID] WHERE Projects.ObjType=1)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 13:50

Вроде так

SELECT *
FROM Packs
WHERE Packs.N NOT IN (SELECT N FROM Packs INNER JOIN Projects ON Packs.N=Projects.[Obj ID] WHERE Projects.ObjType=1)


работает.

Насчёт
"Access :: LEFT JOIN с константой"


добавление скобок ничего не решает. К тому же многое зависит от того, на каком компе подобный запрос выполняется. На одних он возвращает нулевое кол-во записей, на других выводит ругательство.
Последний раз редактировалось Alexanbar 04.11.2005 (Пт) 13:58, всего редактировалось 1 раз.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 13:56

Alexanbar писал(а):Вроде так

SELECT *
FROM Packs
WHERE Packs.N NOT IN (SELECT N FROM Packs INNER JOIN Projects ON Packs.N=Projects.[Obj ID] WHERE Projects.ObjType=1)


работает, вот только не могу пока уловить смысл.

Подчинённый запрос возвращает набор уникальных идентификаторов Packs (ведь N - уникальный идентификатор?), для которых есть соответствующие записи в Projects. Соответственно, в итог попадают те Packs, чей идентификатор NOT IN.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 13:59

GSerg писал(а):Подчинённый запрос возвращает набор уникальных идентификаторов Packs (ведь N - уникальный идентификатор?), для которых есть соответствующие записи в Projects. Соответственно, в итог попадают те Packs, чей идентификатор NOT IN.


Вроде усвоил.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 04.11.2005 (Пт) 14:17

Alexanbar писал(а):добавление скобок ничего не решает.

Имеются в виду не скобки для каждого условия, а для всей секции ON в целом.
Alexanbar писал(а):К тому же многое зависит от того, на каком компе подобный запрос выполняется. На одних он возвращает нулевое кол-во записей, на других выводит ругательство.

Это теоритические рассуждения или ты пробовал? Интересуюсь не для того чтобы уязвить, а чтобы в будущем не наступать на такие грабли.

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 18:14

Нет, обидеть никого не хотелось. Просто на эти грабли уже наступал:

" .... FROM Packs LEFT JOIN Projects ON (Packs.N = Projects.[Obj ID] and Projects.ObjType=1)


- на моём компе это работало, правда впоследствии выявилась скрытая ошибка, а на другом выдавалась ошибка.

Сообщение об ошибке пропало после того, как были внесены изменения:


FROM Packs LEFT JOIN Projects ON (Packs.N = Projects.[Obj ID] )


хотя скрытая ошибка так и оставалась. Собственно, ошибкам подобного типа и была посвящена эта тема.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 04.11.2005 (Пт) 20:35

Alexanbar писал(а):выявилась скрытая ошибка, а на другом выдавалась ошибка
...
хотя скрытая ошибка так и оставалась

Скрытая - это как? И если скрытая, то откуда знаешь, что она там есть?

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 04.11.2005 (Пт) 22:21

Сделал сейчас такой тест. Один и тот же запрос выпорлнил в MS Access-97 и в MS Access-2003 (с предварительно преобразованной в этот формат базой):


Select [Packs].[N], [Packs].[Name], [Packs].[Folder_], [Packs].[Deleted], [Packs].[Comments], [Packs].[InsArcPrj_] , [Projects].[Obj ID], [Projects].[ObjType], [Projects].[Project], [Projects].[InsArcPrj] FROM Packs LEFT JOIN Projects ON (Packs.N = Projects.[Obj ID] and Projects.ObjType=1) WHERE ( (Packs.[Deleted]=False) and (Projects.[Obj ID] Is Null) ) order by Packs.[N] desc;


В первом случае (97) результат - 0 записей, во втором - 5 записей.

Это я к тому, что, по всей видимости, конструкция
ON (Packs.N = Projects.[Obj ID] and Projects.ObjType=1)

не во всех версиях приводит к правильному результату (а может быть, ещё что-нибудь).
Последний раз редактировалось Alexanbar 05.11.2005 (Сб) 0:52, всего редактировалось 1 раз.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.11.2005 (Пт) 23:48

Начиная с какого-то там Access появилась поддержка SQL-92, выбирается в параметрах, при этом предупрждают, что возможно изменение поведения запросов... Случайно не включена эта галка?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 05.11.2005 (Сб) 0:10

GSerg писал(а):Начиная с какого-то там Access появилась поддержка SQL-92, выбирается в параметрах, при этом предупрждают, что возможно изменение поведения запросов... Случайно не включена эта галка?


В 2003 у меня не включена, а в 97 такого параметра нет.


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 1

    TopList