Как получить SQL для добавления переменной к имени поля в предложении where? - PullRequest
1 голос
/ 25 января 2010

Я работаю с MS-Access. У меня есть таблица, которую я изменяю, поля таблицы:

NumberOfCycles, s1,s2,s3,s4...s8

строки содержат различное количество s, в некоторых все восемь, а в некоторых меньше (количество s определяется NumberOfCycles). Теперь у меня есть избыточные данные, поэтому у меня будет что-то вроде этого.

NumberOfCycles, s1,s2,s3,s4...s8  
       4        1   0  1  0  
       4        0   1  0  
       4        1   0  
       4        0  

Я хочу только первый ряд. Я попытался решить эту проблему, добавив утверждение в мое предложение where:

where 's' + NumberOfCycles <> Null

Это не работает, потому что SQL просто сравнивает строку 's4' с нулем. Как я могу получить его, чтобы он сравнивал значение поля s4 (или любое другое значение NumberOfCycles) с Null?

Ответы [ 4 ]

4 голосов
/ 25 января 2010

Стандартный SQL:

WHERE
     CASE NumberOfCycles
          WHEN 1 THEN s1
          WHEN 2 THEN s2
          WHEN 3 THEN s3
          WHEN 4 THEN s4
          WHEN 5 THEN s5
          WHEN 6 THEN s6
          WHEN 7 THEN s7
          WHEN 8 THEN s8
          ELSE NULL
     END IS NOT NULL  -- Can't use <> for NULL

Для MS Access я считаю, что это будет:

WHERE
     SWITCH(NumberOfCycles=1, s1, NumberOfCycles=2, s2, NumberOfCycles=3, s3...) IS NOT NULL
3 голосов
/ 25 января 2010
WHERE CASE WHEN NumberOfCycles = 7 THEN s7 
           WHEN NumberOfCycles = 6 THEN s6 
           ...
      END IS NOT NULL

Никогда не проверяйте на <> NULL. Даже NULL не равно NULL, и поэтому всегда возвращает true.

1 голос
/ 26 января 2010

Грубый пример с использованием запроса Union.

SELECT a.Cycle, a.NoCycles, a.CS, a.CSName 
FROM
    (SELECT c.Cycle, c.NoCycles, c.s1 As CS, "s1" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s2 As CS, "s2" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s3 As CS, "s3" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s4 As CS, "s4" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s5 As CS, "s5" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s6 As CS, "s6" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s7 As CS, "s7" As CSName
    FROM CycleTable c
    UNION ALL
    SELECT c.Cycle, c.NoCycles, c.s8 As CS, "s8" As CSName
    FROM CycleTable c) a

WHERE a.Cycle=4 AND a.CSName="s4"
0 голосов
/ 25 января 2010

Я согласен с комментарием, вы должны рассмотреть проект на наличие альтернатив.

С точки зрения существующего дизайна мне представляется два варианта ...
1. Создайте строку запросав VBA, затем выполните его
2. Используйте оператор CASE в предложении WHERE

Признаюсь, я не знаю синтаксис Access, так что вот синтаксис SQL Server для вашего вдохновения ...

WHERE
   CASE NumberOfCycles
      WHEN 1 THEN s1
      WHEN 2 THEN s2
      WHEN 3 THEN s3
      WHEN 4 THEN s4
   END
   IS NOT NULL

Это, однако, неэффективно, так как сканирует каждую запись и не может использовать индексы и т. Д.

РЕДАКТИРОВАТЬ

ТакжеОбратите внимание, что на основе вашего примера и фактического вопроса, если у вас когда-либо будет "NumberOfCycles = 3", но записи, в которых заполнены s3 и s4, возвращаются обе записи.

Я полагаю, вам будет рекомендовано иметь поле«цикл», который описывает цикл, в котором были заполнены данные.

   Cycle | Number Of Cycles | s1 | s2 | s3 | s4
      1  |                4 |  0 |  - |  - |  -
      2  |                4 |  0 |  1 |  - |  -
      3  |                4 |  0 |  1 |  0 |  -
      4  |                4 |  0 |  1 |  0 |  1

Тогда вам просто нужно найти «Cycle = NumberOfCycles»

РЕДАКТИРОВАТЬ

Очевидно, что в Access есть ужасное выражение SWITCH..

WHERE
   SWITCH(
      NumberOfCycles=1, s1,
      NumberOfCycles=2, s2,
      NumberOfCycles=3, s3,
      NumberOfCycles=4, s4
   )
   IS NOT NULL

Или вы можете перейти к ужасному выражению ИЛИ ...

WHERE
   (NumberOfCycles=1 AND S1 IS NOT NULL)
OR (NumberOfCycles=2 AND S2 IS NOT NULL)
OR (NumberOfCycles=3 AND S3 IS NOT NULL)
OR (NumberOfCycles=4 AND S4 IS NOT NULL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...