более одной строки, возвращенной подзапросом, используемым в качестве выражения в запросе postgreSql с предложением IN - PullRequest
0 голосов
/ 31 августа 2018

У меня проблема с запросом в postgreSql. Ниже приведен запрос.

UPDATE t_e20so1_fieldrulethen AS fthen 
SET    c_thenfieldid = t1.c_fieldschemaid 
FROM   t_sys_fieldschema AS t1 
WHERE  fthen.c_lyrathenfieldid = t1.c_lyraid 
   AND fthen.c_rulefor = 5 
   AND t1.c_fieldtype = 18 
   AND t1.c_tablegroupsid IN ( 
       CASE 
         WHEN fthen.c_iffieldid = t1.c_id THEN (SELECT 
         c_targettableid 
         FROM t_sys_tablegroups 
         WHERE c_parentid = 'c0b2f85c-bc93-466b-a54d-b1330440db98') 
         ELSE (SELECT c_targettableid 
               FROM   t_sys_tablegroups 
               WHERE  c_parentid = 
                      'c0b2f85c-bc93-466b-a54d-b1330440db98') 
       END ); 

Согласно приведенному выше запросу, я обновляю t_e20so1_fieldrulethen таблицу из t_sys_fieldschema. Одно из условий для проверки - t_sys_fieldschema.c_tablegroupsid должен иметь определенные значения, и я извлекаю их из таблицы t_sys_tablegroups.

Выше запрос дает мне ошибку, как показано ниже:

ERROR:  more than one row returned by a subquery used as an expression
SQL state: 21000

Здесь, если я удаляю регистр из запроса (ниже я имею в виду), он работает правильно.

UPDATE t_e20so1_fieldrulethen AS fthen 
SET    c_thenfieldid = t1.c_fieldschemaid 
FROM   t_sys_fieldschema AS t1 
WHERE  fthen.c_lyrathenfieldid = t1.c_lyraid 
   AND fthen.c_rulefor = 5 
   AND t1.c_fieldtype = 18 
   AND t1.c_tablegroupsid IN (SELECT c_targettableid 
                              FROM   t_sys_tablegroups 
                              WHERE 
           c_parentid = 'c0b2f85c-bc93-466b-a54d-b1330440db98') 

Теперь у меня есть только один запрос на выборку в предложении «IN».

1 Ответ

0 голосов
/ 31 августа 2018

Я проверил этот тип оператора case (два вложенных выбора) - и это невозможно сделать таким образом. Вы генерируете два отдельных списка в одном случае. Один список для всех записей, где fthen.c_iffieldid = t1.c_id, а другой для инструкции ELSE.

Как я уже писал много раз, никогда не используйте вложенные селекторы в предложении "IN". Это убивает производительность и вызывает много проблем. Используйте «EXISTS». Поскольку ваш CASE кажется избыточным (и WHEN, и ELSE возвращают одно и то же значение), измените его таким образом, и он будет быстрее.

UPDATE t_e20so1_fieldrulethen AS fthen 
   SET c_thenfieldid = t1.c_fieldschemaid 
  FROM t_sys_fieldschema AS t1 
 WHERE fthen.c_lyrathenfieldid = t1.c_lyraid 
   AND fthen.c_rulefor = 5 
   AND t1.c_fieldtype = 18 
   AND exists (select from t_sys_tablegroups t2 
                where t1.c_tablegroupsid=t2.c_targettableid
                  and  c_parentid = 'c0b2f85c-bc93-466b-a54d-b1330440db98');
...