Есть ли способ заставить это дело работать? - PullRequest
1 голос
/ 24 января 2020

Я получаю следующую ошибку с кодом ниже:

ОШИБКА: аргумент AND должен быть логическим типом, а не типом, меняющимся в LINE 9: и регистр ^ SQL состояние: 42804 символа : 300

Этот код делает несколько вещей, но у меня возникли проблемы с описанием ситуации. Я хочу, чтобы этот фрагмент искал случаи, когда совпадают первые 11 символов двух строк. Если это не так для данной записи, посмотрите на первые 10 символов, затем на 9, затем на 8. После этого нулевой является приемлемым результатом.

select cm.course_id, cm.course_name, cmp.course_id as parentcourse, 
(select cmm.course_id
from course_main cmm
where cmm.course_id ilike '%Master%'
    and cmm.course_id not ilike '%Ground%'
    and cmm.course_id not ilike '%Surprise%'
    and cmm.course_id not ilike '%emba%'
    and cmm.row_status != 2
    and case 
         when left(cm.course_id,11) = left(cmm.course_id,11) 
            then cmm.course_id 
            else 
            case 
            when left(cm.course_id,10) = left(cmm.course_id, 10) 
                then cmm.course_id 
                else 
                case 
                when left(cm.course_id,9) = left(cmm.course_id, 9) 
                    then cmm.course_id 
                    else 
                    case 
                    when left(cm.course_id,8) = left(cmm.course_id,8) 
                        then cmm.course_id 

                    end
                end
            end
        end) as mastercourse
from course_main as cm
left join course_course cc
on cc.crsmain_pk1 = cm.pk1
left join course_main cmp
on cmp.pk1 = cc.crsmain_parent_pk1
where cm.course_id ilike '%-ES-2020-%'
    and cm.row_status != 2
    and cmp.course_id is null
    order by cm.course_id;

Спасибо за помощь Z4. Я попытался применить ваши предложения и смог обойти ошибку. Проблема с этими строками заключается в том, что я пытаюсь сопоставить что-то вроде:

'NRSG-46009-ES-2020-OA' с 'NRSG-46009-Master-Online-Content' в среде, которая также содержит это:

'NRSG-4600-Master-Online-Content' 'NRSG-46003-Master-Online-Content' 'NRSG-4600-Master-Online-Content'

Если я посмотрю в первые 8 символов, прежде чем смотреть на первые 11, я получу несоответствия. Итак, я смотрю на 11 в первую очередь. Если нет ничего подходящего, посмотрите на первую десятку и так далее. Строки из 8 - это слово в нашей схеме идентификации с примерами, подобными этому:

'IT-7003-ES-2019-AE', который должен соответствовать 'IT-7003-Master-Online-Content'

В любом случае, я воспользовался вашим советом и выполнил следующее:

select distinct cm.course_id, cm.course_name, cmp.course_id as parentcourse, 
case 
when left(cm.course_id,11) = left(cmm.course_id,11) 
    then cmm.course_id 
    else 
    case 
    when left(cm.course_id,10) = left(cmm.course_id, 10) 
        then cmm.course_id 
        else 
        case 
        when left(cm.course_id,9) = left(cmm.course_id, 9) 
            then cmm.course_id 
            else 
            case 
            when left(cm.course_id,8) = left(cmm.course_id,8) 
                then cmm.course_id 
            end
        end
    end
end as mastercourse
from course_main cm
    left join course_course cc
        on cc.crsmain_pk1 = cm.pk1
    left join course_main cmp
        on cmp.pk1 = cc.crsmain_parent_pk1
    left join course_main cmm
        on cm.pk1 = cm.pk1
where cm.course_id ilike '%-ES-2020-%'
    and cm.row_status != 2
    and cmp.course_id is null
    and cmm.course_id ilike '%Master%'
    and cmm.course_id not ilike '%Ground%'
    and cmm.course_id not ilike '%Surprise%'
    and cmm.course_id not ilike '%emba%'
    and cmm.row_status != 2
    order by cm.course_id;

Кажется, это работает, но я получаю повторяющиеся результаты:

результаты ' успешный запрос

Есть идеи, как исключить дубликаты?

1 Ответ

1 голос
/ 24 января 2020

Во-первых, действительно нет необходимости использовать такой сложный оператор case. Если первые 8 символов не совпадают, то, конечно, первые 9 или 10 или 11 тоже не будут совпадать, верно? Так что просто избавьтесь от всего этого и проверьте только первые 8:

CASE
  WHEN LEFT(cm.course_id, 8) = LEFT(cmm.course_id, 8)
    THEN cmm.course_id
END

Далее, оператор CASE должен выйти из предложения WHERE и войти в список SELECT (это это то, что вызывает ошибку boolean type):

select
  [...]
  (
    select
      CASE
        WHEN LEFT(cm.course_id, 8) = LEFT(cmm.course_id, 8)
          THEN cmm.course_id
      END
    from 
      course_main cmm
    where 
      cmm.course_id ilike '%Master%'
      and cmm.course_id not ilike '%Ground%'
      and cmm.course_id not ilike '%Surprise%'
      and cmm.course_id not ilike '%emba%'
      and cmm.row_status != 2
  ) as mastercourse
FROM
  [...]

Я ничего не знаю о данных, которые вы пытаетесь захватить здесь, но я также настоятельно рекомендую потратить некоторое время на переосмысление использование коррелированного подзапроса. Даже если это правильно описывает набор данных, который вы хотите, подзапрос действительно неэффективен. Я бы предположил, что он может быть полностью заменен на LEFT JOIN в основном теле запроса (скорее всего, само присоединение от course_main к себе).

...