Microsoft Access 97 / XP отказывается при левом соединении на нескольких столбцах - Vista / 7 в порядке - PullRequest
0 голосов
/ 10 января 2012

Я пытаюсь выполнить левое соединение двух таблиц, чтобы получить все значения, которые не существуют в таблице 2 или имеют нулевое состояние:

Таблица 1 имеет ROID, равный

Таблица2 имеет идентификатор длинный, тип длинный и текст состояния.

Это отлично работает на Vista и Win 7 (я получаю все записи, которых нет в V), но я не получаю записи на XP,

  SELECT roid
  FROM
  wo AS w LEFT JOIN VFlag As V ON (w.roid = V.ID AND V.Type = 2)
  WHERE
  (V.Status is Null) 

Когда я удаляю V.Type = 2, он отлично работает на XP / Vista / 7, но мне нужно также пройти квалификацию на Type:

SELECT roid
  FROM
  wo AS w LEFT JOIN VFlag As V ON (w.roid = V.ID)
  WHERE
  (V.Status is Null)  

Это и вVB6 с использованием ADO и VisData.Попытка ГДЕ isnull (V.Status) не имела никакого значения.Машины XP (две проверены) SP3.

Ответы [ 3 ]

1 голос
/ 10 января 2012

Вы пытались поместить V.Type = 2 в предложении WHERE вместо объединения?

0 голосов
/ 28 февраля 2014

Я немного опоздал на это - но я только что натолкнулся на то, что, кажется, та же проблема на Access 2003 Кажется, ошибка исправлена ​​в последней версии JET. Так что вполне можете объяснить симптомы, которые вы видели и как исправить в Windows 7.

MS KB275058

mikecro

0 голосов
/ 12 января 2012

Во-первых, это известная проблема , когда внешнее соединение Access не соответствует стандартам, дает неожиданные результаты и в результате менее выразительно. Команда SQL Server хотела исправить эту «ошибку», но была отброшена командой Windows ; крайне маловероятно, что впоследствии двигатель будет починен.

Во-вторых, нулевые значения в SQL - это вообще катастрофа. Стандарт SQL не может определить трехзначную логику. Доступ, в частности, также не соответствует трехзначной логике и имеет многочисленные несоответствия. Лучше всего избегать нулевого значения, а внешнее объединение специально разработано для генерации нулевых значений.

В-третьих, всегда есть нечто большее, чем способ выразить одно и то же в SQL. Требуемый вам реляционный оператор: полуразница a.k.a. antijoin . Ваша спецификация гласит: «получить все значения, которые не существуют в таблице 2», поэтому рассмотрите возможность использования NOT EXISTS, например.

SELECT roid
  FROM wo AS w 
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM VFlag As V 
                    WHERE w.roid = V.ID 
                          AND V.Type = 2
                  );

Я не уверен, должен ли подзапрос дополнительно тестировать V.Type IS NULL, потому что вы включили детали реализации (LEFT OUTER JOIN) в свою спецификацию, и я не вижу деревья для дерева:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...