2015-04-14 5 views
0

Я пытаюсь выполнить запрос в DB2. Но он бросает следующие ошибки:Подзапрос DB2 не работает с использованием инструкции IN SQLCODE 115

Error: DB2 SQL Error: SQLCODE=-115, SQLSTATE=42601, SQLERRMC=IN, DRIVER=4.8.86 
SQLState: 42601 
ErrorCode: -115 
Error: DB2 SQL Error: SQLCODE=-514, SQLSTATE=26501, SQLERRMC=SQL_CURSH200C1; STMT0001, DRIVER=4.8.86 
SQLState: 26501 
ErrorCode: -514 

Какой does'nt иметь смысл, как мой запрос выглядит правильно:

SELECT ROW_NUMBER() OVER() AS ID, 
CONCAT(TRIM(TB1.ROW1),CONCAT('_',TRIM(TB1.ROW2))) AS CODE_DESCRIPTION, 
CASE 
    WHEN TRIM(TB1.ROW1) IN (SELECT T1.ROW1 FROM DB1.TABLE1 T1 WHERE T1.ROW3 = 'TEST') 
    THEN 'Valid' 
    ELSE 'Invalid' 
END, 
TB1.* FROM DB1.TABLE1 TB1 
WHERE TB1.ROW3 = 'CLASS1'; 

SQLCODE 115 означает, что сравнение является недействительным. Который не ?

Обновление: Что я пытаюсь сделать здесь. У меня есть таблица Table1 (имя изменено для простоты). Ниже приведена часть контента.

**Row3** **Row1**        **Row2**                                                                             
KSASPREM SRQ       0 0 Auto Carry                                                                       SRQ     
KSASPREM SCG       0 0 BRT Buses                                                                       SCG     
KSASPREM SCE       0 0 Buses                                                                        SCE     
KSASPREM SRR       0 0 Buses                                                                        SRR     
KSASPREM SDC       0 0 Domestic All Risks                                                                     SDC     
KSASPREM SDA       0 0 Domestic Buildings                                                                     SDA  

Задача для выполнения:

  1. Получить все значения из Table1, где Row3 является KSASPREM
  2. Результат должен содержать один дополнительный «Действительный» значение столбца Да/Нет, если значение Row1 не в значениях, полученных из таблицы 1, где Row3 является «TEST»

Надеюсь, я сделал себя ясным и не более запутанным?

Любая помощь? Thanks Ps. Обновлен запрос

+0

Насколько я знаю, вы должны иметь 'THEN' как часть выражения' CASE'. Что вы пытаетесь сделать там? Даже если это допустимый синтаксис, похоже, что это не повлияет. Кроме того, 'Table1', кажется, имеет несколько столбцов (хотя очень странно названо' row1' и т. Д.), Поэтому 'SELECT *' приведет к синтаксическим ошибкам из-за несоответствия счетчика. Возможно, если бы вы показали свой стол и желаемые результаты? Обратите внимание, что результаты 'ROW_NUMBER()' будут последовательными, но не детерминированными (каждый раз каждый раз). –

+0

Спасибо за ответ. Я обновил запрос. Я добавил THEN и ELSE, все еще ту же ошибку. – punkck

+1

Жалоба на то, что 'IN + subquery' недопустим как часть инструкции' CASE', по-видимому (помимо дополнительной синтаксической ошибки отсутствующей запятой после 'END ...'). Вероятно, вы не хотите делать это как подзапрос в 'SELECT' в любом случае - он, вероятно, будет запускаться один раз для каждой строки результатов, что может быть дорогостоящим. Вам будет лучше обслуживать, выполняя 'LEFT JOIN' +' COALESCE (..., 'Invalid') '- будет ли когда-нибудь только одна строка' 'TEST''? И вам, скорее всего, не нужно будет вызывать 'TRIM (row1)', если нет похожих строк с дополнительными пробелами (которые должны быть исправлены ...) –

ответ

0

Как и во многих вещах, ответ JOIN (здесь, LEFT JOIN). В частности, мы должны поместить (слегка измененный) подзапрос в качестве ссылки на таблицу:

LEFT JOIN (SELECT DISTINCT row1, 'Valid' as valid 
      FROM Table1 
      WHERE row3 = 'TEST') AS Test 
     ON Test.row1 = TB1.row1 
  • LEFT JOIN говорит движок запросов, «строка в этой другой таблице не требуется».
  • DISTINCT говорит, «для всех комбинаций значений в этих столбцах, дайте мне только одну строку»
  • Использование постоянного значения - 'Valid' - возвращает, что постоянное значение.

... так что это становится нам столик (виртуальный, темп), содержащий уникальные row1 записи, где в row3 = 'test'.

Вот полный запрос:

SELECT ROW_NUMBER() OVER(ORDER BY TB1.row1) AS ID, 
     TRIM(TB1.ROW1) || '_' || TRIM(TB1.ROW2) AS CODE_DESCRIPTION, 
     COALESCE(Test.valid, 'Invalid') AS valid, 
     TB1.row3, TB1.row1, TB1.row2 
FROM Table1 TB1 
LEFT JOIN (SELECT DISTINCT row1, 'Valid' as valid 
      FROM Table1 
      WHERE row3 = 'TEST') Test 
     ON Test.row1 = TB1 .row1 
WHERE TB1.ROW3 = 'KSASPREM' 

SQL Fiddle Example

COALESCE(...) возвращает первое непустое значение встречается в списке значений. Так как, если нет Test строки, Test.valid будет пустым, то выходы 'Invalid' для TB1 строк без соответствующей строки Test. (Внутренне он звонит CASE, я считаю, это просто делает его красивее)

Обратите внимание, что:

  • Я поставил ORDER BY в пункте OVER, чтобы вернуться (в основном) стабильные результаты.Если вы когда-либо планируете запускать это раз, это не имеет значения, но если вам нужно запустить его несколько раз и получить согласованное значение ID, вам нужно будет использовать то, что не будет перетасовано.
  • DB2 (и, очевидно, PostgreSQL) поддерживает || как оператор concat. Это делает заявления о чтении намного легче понять.
  • Никогда не используйте SELECT *, это не безопасно по нескольким причинам. Всегда указывайте, какие столбцы вы хотите.
+0

Пятно на: D Спасибо, часовой завод. Решила мою проблему. – punkck

Смежные вопросы