Исключение SQL-запроса сложного доступа

Для базы данных доступа, которая выглядит следующим образом: (Все текстовые поля)

Co1 Co2 Co3 Co4
A   k   t   N1
B   k   t   N2
A   m   t   N3
B   k   z   N4
A   k   z   N5
C   m   t   N6
C   k   z   N7
C   k   t   N8
A   k   t   N9
C   m   t   N10

Мне нужно создать какие-то отчеты, которые будут делать следующее:

В результатах необходимо выбрать строки:

  1. Сначала заказал Co1
  2. затем заказал Co2
  3. включать только данные, где Co3 = t или r
  4. когда Co3 НЕ является ни t, ни r, тогда все другие строки с предыдущим C04, где Co1 И Co2 были такими же, как текущая строка, также исключаются.

1,2 и 3 чрезвычайно легко сделать (предложение Order by и Where соответственно), но можно ли выполнить # 4 в доступе к SQL? Если это невозможно, я сделаю небольшое приложение C#, которое перебирает данные, но я чувствую, что это должно быть возможно сделать в SQL, и если это возможно, это определенно будет намного лучше.

Фактический запрос и база данных более сложны, но в № 4 я застрял.

В примере, который я привел, результат будет таким:

A   m   t   N3
A   k   t   N9
C   m   t   N6
C   m   t   N10
C   k   t   N8

Я считаю, что это охватывает все возможные случаи.

Точность, мы используем четвертый столбец (C4 в этом примере) для определения порядка, но это текстовое поле с символами и цифрами. Поле представляет собой букву, за которой следуют 2 цифры: A01, A02,..A99, B01 и т. д. Точность № 2: я не виноват в дизайне этой базы данных. :П

Итак, гуру SQL среди нас: можно ли это сделать в Access SQL? Как?

Большое спасибо за любую помощь, которую вы можете предоставить.


person tb.    schedule 03.06.2009    source источник
comment
Я не понимаю вашего ограничения № 4. Не могли бы вы перефразировать это? тогда все остальные строки с предыдущим C04, что это значит?   -  person Mark Canlas    schedule 03.06.2009
comment
@Unknown Google: Андомар был очень прав, когда улучшил формулировку моего № 4, изменив ее: нам нужно исключить строки, для которых есть более поздняя строка, где Co3 не является t и не r, но где более поздняя строка имеет тот же Co1 и СО2   -  person tb.    schedule 03.06.2009


Ответы (3)


Если я правильно вас понял:

когда Co3 НЕ является t и r, тогда все другие строки с предыдущим C04, где Co1 И Co2 были такими же, как текущая строка, также исключаются.

Это эквивалентно исключению строк, для которых существует более поздняя строка с определенными условиями. Вы можете сделать это с предложением NOT EXISTS:

select *
from YourTable cur
where cur.Co3 in ('t','r')
and not exists (
    select *
    from YourTable later
    where cur.Co1 = later.Co1 
    and cur.Co2 = later.Co2
    and later.Co3 not in ('t','r') 
    and CInt(Mid(later.Co4,2)) > CInt(Mid(cur.Co4,2))
)
order by cur.Co1, cur.Co2 desc, CInt(Mid(cur.Co4,2))

Теперь N10 обычно не больше, чем N5. Вот для чего нужен CInt(Mid(...,2)): он превращает N10 в число 10, а число N5 в 5.

person Andomar    schedule 03.06.2009
comment
Большое спасибо Andomar, пришлось немного доработать, но в целом это именно то, что мне было нужно. - person tb.; 04.06.2009

Модификация запроса Andomar, в которой учитываются значения в Co4, начинающиеся с разных букв, с использованием значения ASCII кода символа для определения порядка. Я предполагаю, что диапазон составляет A01...A99, B01...B99 и т. д., и что B01 следует считать «позже», чем A99.

select *
from Table1 cur
where not exists (
    select 1
    from Table1 later
    where cur.Co1 = later.Co1 
    and cur.Co2 = later.Co2
    and later.Co3 not in ('t','r') 
    and (asc(left(later.Co4,1)) * 100) + CInt(Mid(later.Co4,2)) > (asc(left(cur.Co4,1)) * 100) + CInt(Mid(cur.Co4,2))
)
and cur.Co3 in ('t','r')
order by cur.Co1, cur.Co2
person Ed Harper    schedule 03.06.2009

Еще не ответ, но код установки для других ответчиков.

create table #boost (
  Co1 char(1),
  Co2 char(1),
  Co3 char(1),
  Co4 char(3)
)

insert into #boost values ('A', 'k', 't', 'N1')
insert into #boost values ('B', 'k', 't', 'N2')
insert into #boost values ('A', 'm', 't', 'N3')
insert into #boost values ('B', 'k', 'z', 'N4')
insert into #boost values ('A', 'k', 'z', 'N5')
insert into #boost values ('C', 'm', 't', 'N6')
insert into #boost values ('C', 'k', 'z', 'N7')
insert into #boost values ('C', 'k', 't', 'N8')
insert into #boost values ('A', 'k', 't', 'N9')
insert into #boost values ('C', 'm', 't', 'N10')
person Mark Canlas    schedule 03.06.2009
comment
Если вы пропустили это, это вопрос MS Access ;-) - person Andomar; 03.06.2009
comment
Это даже отдаленно недействительно Access SQL: D Кроме того, должно было быть редактирование исходного сообщения. (Или прокомментируйте, если у вас нет представителя.) - person Oorang; 04.06.2009