【问题标题】:Understanding explicit type casts in SQL了解 SQL 中的显式类型转换
【发布时间】:2017-02-16 09:35:02
【问题描述】:
SELECT * 
FROM lookup_type 
WHERE type_group = 'enquiry' 
  AND type_sub_group = 'category' 
  AND type_attribute IN (SELECT prod_id 
                         FROM product 
                         WHERE prod_id IN (SELECT option_prod_id 
                                           FROM product_option 
                                           WHERE option_id IN (SELECT link_option_id 
                                                               FROM product_link 
                                                               WHERE link_member_id = '146')));

在上面的查询中,我想在查找表中选择一条记录。但是我从我的 postgreSQL 客户端收到以下错误。

错误:运算符不存在:字符变化 = 整数
第 1 行:...uiry' 和 type_sub_group='category' 和 type_attr in(SELECT ...
^

提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。

type attrvarchar 列,prod_id 是整数列。

我做错了什么,我该如何解决?非常感谢您解释如何在未来避免这种情况。

【问题讨论】:

  • 您为什么将苹果与橙子进行比较?将相同类型的信息存储为一个表中的 varchar 和另一个表中的整数是没有意义的。

标签: sql postgresql


【解决方案1】:

PostgreSQL 是强类型 - 每个值都有一个定义的类型,每个函数和运算符都被定义为使用特定的类型。

有一个运算符用于比较两个VarChar 值,一个不同的运算符 用于比较两个Integer 值。两者都拼写为=,但它们是 Postgres 系统目录中的单独条目。由于没有名为= 的运算符在一侧使用VarChar,在另一侧使用Integer,这解释了“运算符不存在”消息。

在实践中,经验法则是您需要使= 符号的两侧为同一类型,以便可以比较它们。这可以使用标准 SQL CAST(value AS type) 函数来完成,该函数将值从一种类型转换为另一种类型。

在这种情况下,您希望内部 SELECT 的结果全部为 VarChars,以便可以将它们输入到 IN 子句中,因此您可以编写:

... and type_attribute in (SELECT CAST(prod_id as VarChar) ...

整数始终可以转换为字符串,因为您始终可以使用数字写出数字。如果你知道一个字符串只包含数字,你也可以用另一种方式转换,例如CAST(type_attribute AS int).

【讨论】:

    【解决方案2】:

    您正在检查 type_attribute,它是一个带有整数的 varchar 字段,即 prod_id。您可以做的一件事是在子查询中将 cast prod_id 键入为 varchar。

    SELECT Cast(prod_id As varchar) 
    

    【讨论】:

      【解决方案3】:

      所以你的查询是这样的:

      SELECT * 
          FROM lookup_type 
          WHERE type_group = 'enquiry' 
              and type_sub_group='category' 
              and type_attribute in (
                  SELECT prod_id 
                  FROM product 
                  WHERE prod_id in (
                      SELECT option_prod_id 
                      FROM product_option 
                      WHERE option_id in (
                          SELECT link_option_id 
                          FROM product_link 
                          WHERE link_member_id = '146'
                          )
                      )
                  );
      

      让我们从内部查询开始:

                      SELECT link_option_id 
                      FROM product_link 
                      WHERE link_member_id = '146'
      

      如果link_option_idinteger,但来自上层嵌套的option_idvarchar 类型,您将遇到问题。因此,您需要cast 结果并拥有它:

                  SELECT cast(link_option_id,varchar) 
                  FROM product_link 
                  WHERE link_member_id = '146'
      

      你懂的。必须沿用相同的逻辑。

      以下是有关 CAST 函数的更多附加信息(快速谷歌搜索): http://www.postgresqltutorial.com/postgresql-cast/

      【讨论】:

        【解决方案4】:

        在 PostgreSQL 中,您可以使用 :: 表示法进行转换,例如

        SELECT * 
        FROM lookup_type 
        WHERE type_group = 'enquiry' 
         and type_sub_group='category' 
         and type_attribute in (SELECT prod_id::varchar 
                                FROM product 
                                WHERE prod_id in (SELECT option_prod_id 
                                                  FROM product_option 
                                                  WHERE option_id in (SELECT link_option_id 
                                                                      FROM product_link 
                                                                      WHERE link_member_id = '146')));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-15
          • 2016-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-03
          相关资源
          最近更新 更多