【问题标题】:more than one row returned by a subquery used as an expression in postgreSql query with IN clause子查询返回的多行用作带有 IN 子句的 postgreSql 查询中的表达式
【发布时间】:2019-02-06 10:33:19
【问题描述】:

我在 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_sys_fieldschema 更新t_e20so1_fieldrulethen 表。要检查的条件之一是 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”子句中只有一个选择查询。

【问题讨论】:

  • 那你的问题是什么?
  • 以上是错误的查询(第一个),我需要弄清楚如何以正确的方式将条件放入“IN”子句中。
  • 不相关但可能很重要 - 对我来说,案例中的两个陈述对于 WHEN 和 ELSE 看起来完全相同。
  • @GrzegorzGrabek 确切地说,只有一个 select 语句没有给出错误,而是给出了数据。但是当我在“IN”子句中使用两个语句时,它给出了提到的错误。
  • 我已经重新检查了这个 CASE 条件。在一种情况下,您返回两个单独的列表,一个用于 fthen.c_iffieldid = t1.c_id,第二个用于 ELSE。对于 IN 你只能有一个列表。为了将来停止对 IN clasue 和 retrurnig 结果使用嵌套选择,这是非常非常糟糕的做法。

标签: postgresql switch-statement in-clause


【解决方案1】:

我已经检查过这种 case 语句(两个嵌套选择) - 不能那样做。您在一个 CASE 中生成两个单独的列表。 一个列表包含 fthen.c_iffieldid = t1.c_id 的所有记录,另一个用于 ELSE 语句。

正如我多次写的,永远不要在“IN”子句中使用嵌套选择。它正在扼杀性能并导致许多问题。使用“存在”。 由于您的 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');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多