Что не так с Access? JOIN, ошибка синтаксиса, пропущен оператор

Здравствуйте. Никак не могу врубиться в чем дело. Написал SQL запрос. Пробую в программе DBeaver - все отлично. Результат как и должен быть.
Запускаю его в Access он жалуется на какую то ошибку.
Чего я не вижу??

Проблема в алиасе tab потому как если эту строку убрать то вроде бы нормально отрабатывает. Но без алиаса не знаю как связать одинаковые таблицы по одинаковым полям.

SELECT * FROM simpleword 
LEFT JOIN descriptors ON simpleword.DescriptorID = descriptors.ID
LEFT JOIN simpleword AS tab ON simpleword.BaseWordID = tab.ID
LEFT JOIN descriptors AS tabdesc ON tab.DescriptorID = tabdesc.ID
WHERE (descriptors.Gender = 1 OR descriptors.Gender = 2) AND descriptors.Part = 3 

В режиме конструктора не пробовали построить этот запрос?

Как вариант еще разбить на несколько подзапросов

Да в конструкторе как то не пойму что тут к чему… Дергал дергал… но не то все.

Очень долго все работает в программе потом. Этот запрос сразу достает все нужные данные. Времени на все уходит около секунды. А если запросы разбить то там минуты висит приложение.

попробуйте заменить его на другой, например, на tab1

SELECT * FROM simpleword 
LEFT JOIN descriptors ON simpleword.DescriptorID = descriptors.ID
LEFT JOIN simpleword AS tab1 ON simpleword.BaseWordID = tab1.ID
LEFT JOIN descriptors AS tabdesc ON tab1.DescriptorID = tabdesc.ID
WHERE (descriptors.Gender = 1 OR descriptors.Gender = 2) AND descriptors.Part = 3

Гугл говорит, что скобки нужны.

With Access, each join needs parentheses

https://stackoverflow.com/a/10852571
https://stackoverflow.com/a/10249843

В конструкторе получилось вот такую дичь сделать:

SELECT simpleword.*, descriptors.*, simpleword_1.*, descriptors_1.*
FROM ((simpleword INNER JOIN descriptors ON simpleword.DescriptorID = descriptors.ID) 
INNER JOIN simpleword AS simpleword_1 ON simpleword.BaseWordID = simpleword_1.ID) 
INNER JOIN descriptors AS descriptors_1 ON simpleword_1.DescriptorID = descriptors_1.ID
WHERE (((descriptors.Gender)=1 Or (descriptors.Gender)=2) AND ((descriptors.Part)=3));

Скобки это конечно хрень полная. Странно что DBeaver работает и с простым синтаксисом.

скобки можно убрать ненужные :wink:

SELECT
   simpleword.*,
   descriptors.*,
   simpleword_1.*,
   descriptors_1.* 
FROM
   (
(simpleword 
      INNER JOIN
         descriptors 
         ON simpleword.DescriptorID = descriptors.ID) 
      INNER JOIN
         simpleword AS simpleword_1 
         ON simpleword.BaseWordID = simpleword_1.ID
   )
   INNER JOIN
      descriptors AS descriptors_1 
      ON simpleword_1.DescriptorID = descriptors_1.ID 
WHERE
   (
	(descriptors.Gender = 1 Or descriptors.Gender = 2) AND descriptors.Part = 3
   )

Лишняя работа … ))

А кто нибудь знает существует ли максимальная длина условий WHERE??
Суть в том что мне нужно достать только определенные слова. Этих слов допустим около 300 может быть или больше. Как это сделать за один запрос??

Или может быть механизм есть более удобный для этого?

IN?
https://www.w3schools.com/sql/sql_in.asp

Хм… работает … спасибо ))

А можно еще вопросик?

Задача такая: Из всей базы нужно достать все словоформы и базовое слово для любой формы. Например
слово “работавши” базовое имеет “работать”

SELECT simpleword.*
FROM simpleword 
WHERE (((simpleword.BaseWordID) In (Select BaseWordID FROM simpleword as tabl where tabl.wordform = "работавши")));

Выборка достает все правильные словоформы но она исключает базовое слово.

Базовое слово не имеет индекса базового слова для себя

Если делаю join то время обработки увеличивается сильно. А без него никак не получается

Дался этот in. Если справа в скобках перечень типа x in (1,4,5) то он работает как x=1 or x=4 or x=5. Что равносильно тому, что запрос выполняется трижды. Что происходит когда справа подзапрос затрудняюсь сказать, возможно как-то оптимизируется. Можно же без in что бы не задумываться над этом, заодно и проверить. Например так:

SELECT w2.*
  FROM simpleword w1, simpleword w2
  WHERE w1.wordform = "работавши" and w2.BaseWordID=w1.ID

или с join по современному:

SELECT w2.*
  FROM simpleword w1 INNER JOIN simpleword w2 ON w2.BaseWordID=w1.ID
  WHERE w1.wordform = "работавши"

для добавления базовых слов объединить:

UNION
SELECT *
  FROM simpleword
  WHERE wordform = "работавши"

для access скобки возможно еще расставить )

ЗЫ

если поиск по 300 словам то лучше засунуть их в табличку и запрос с использованием её, а не в лоб перечень этих слов в запрос сувать ) Пусть даже во временную и динамически. Это все равно будет быстрей

А можно пример??

Допустим есть:

SELECT * FROM MyTable WHERE Field1 IN ('Вася', 'Федя', ... и так 300 слов)

Коряво, правда? Да еще очень медленно будет работать.
В MS SQL, например, создал бы динамически временную табличку доступную только соединенному юзеру и засунул бы в неё все эти Васи и Феди:

CREATE TABLE #MyTempTable (Field1 varchar(100) NOT NULL)
INSERT INTO #MyTempTable VALUES(('Вася'),('Федя'), ... )

и сам запрос:

SELECT m.* FROM MyTable m, #MyTempTable t WHERE m.Field1=t.Field1

Для ускорения во временной таблице индекс еще бы создал для поля Field1
В access свои проблемы, нет, например, временных таблиц. Придется извращаться. А зачем вообще подобные вещи в access?

Ну аксес как простая файловая база. Минимум установки. Еще и на хрюше должно работать.
И стоит задача обработки текста с учетом смысловой нагрузки. По простому алгоритм пытается определить особенности текста. Для этого нужно загрузить параметры каждого слова в тексте.

И задача многопользовательская?

SQLite тогда проще, вообще 0 установки, не нужен офис.

Ну офис для базы данных от аксеса тоже совсем не обязателен. Только если многопользовательский доступ потом проблем поимеешь не мало

Нет. Пользователь один.
Офис на компе присутствует. Но насколько я знаю драйвер ставится и без офиса.

А чем он лучше аксеса?

Например нет этой фигни со скобками )
И временные таблицы есть.

Ну и опенсорсный, более популярный для такого применения, поддерживается во всех ОС/ЯП/утилитах.

Акцесс есть смысл брать только если нужен его GUI в офисе.