【问题标题】:SELECT Sub Query PostgreSQLSELECT 子查询 PostgreSQL
【发布时间】:2016-01-22 14:31:35
【问题描述】:

我还是 postgres 的新手。我想在查询的 SELECT 部分中有一个 SELECT 语句,但现在我遇到了一个错误。

SELECT cu.user_name, cu.created_date, cu.updated_date, cu.email_address,
       cua.attribute_name, cua.attribute_value,
       (select to_char(to_timestamp(cua.attribute_value / 1000), 'yyyy-mm-dd HH24:MI:SS')) AS Issue_Update
FROM cwd_user cu
INNER JOIN cwd_user_attribute cua ON cu.id = cua.user_id
WHERE cu.user_name LIKE 'perter%'

我收到以下错误:

错误:运算符不存在:字符变化/整数 第 3 行:(选择 to_char(to_timestamp(cua.attribute_value / 1000), '... ^ 提示:没有运算符与给定名称和参数类型匹配。您可能需要添加显式类型转换。

【问题讨论】:

  • 你不能用 int 分割字符...
  • @a_horse_with_no_name 有没有办法在除法之前将其更改为整数?
  • cast(cua.attribute_value 为整数)
  • 如果是数字,则将其存储为整数。请将数字存储在varchar 列中。
  • @a_horse_with_no_name 我继承了数据库。

标签: sql postgresql subquery


【解决方案1】:
SELECT cu.user_name, cu.created_date, cu.updated_date, 
cu.email_address, cua.attribute_name, cua.attribute_value,
case when (attribute_value like '%True%' or attribute_value like '%False%') then cast(NULL as bigint)
     else CAST(nullif(cua.attribute_value, '') AS bigint)
     end filter_attribute_value,
(select to_char(to_timestamp(
filter_attribute_value / 1000), 'yyyy-mm-dd HH24:MI:SS')) AS Issue_Update
FROM cwd_user cu
INNER JOIN cwd_user_attribute cua ON cu.id = cua.user_id
WHERE cu.user_name LIKE 'perter%'

【讨论】:

  • cua.attribute_value 超出整数数据类型的范围
  • @Kya 尝试使用 bigint
  • 我收到以下错误:错误:整数输入语法无效:“false”
  • 可能你在 varchar 列中有空字符串,它与 NULL 不同,不会被强制转换..所以现在试试..
  • 我想通了。该列包含真、假、一些单词和数字。所以我需要清理一下
【解决方案2】:

显然cua.attribute_value 定义为varchar。错误消息告诉您不能将字符串除以数字。

您需要将 varchar 转换(转换)为整数。而且你根本不需要select

这是您当前设计的解决方法:

SELECT cu.user_name, 
       cu.created_date, 
       cu.updated_date, 
       cu.email_address, 
       cua.attribute_name, 
       cua.attribute_value,
       to_char(to_timestamp(cua.attribute_value::bigint / 1000), 'yyyy-mm-dd HH24:MI:SS') AS Issue_Update
FROM cwd_user cu
  JOIN cwd_user_attribute cua ON cu.id = cua.user_id
WHERE cu.user_name LIKE 'perter%';

::bigint 将字符串转换为整数值。这是 ANSI SQL cast(... as bigint) 运算符的 Postgres 特定语法。详情请见the manual

但如果cua.attribute_value 包含无法转换为整数的值(空字符串'' 已经破坏了这一点),这将失败

正确的解决方案是将数字存储在integer 列中。不要将号码存储为varchar


attribute_nameattribute_value 听起来很像被称为“实体-属性-值”的(反)模式。

如果您确定时间戳信息对于具有特定名称的属性是正确的,您可以执行以下操作以避免转换错误:

       CASE WHEN cua.attribute_name = 'timestamp' THEN
         to_char(to_timestamp(cua.attribute_value::bigint / 1000), 'yyyy-mm-dd HH24:MI:SS') 
       END AS Issue_Update

这将为attribute_name 不是'timestamp' 的所有行返回NULL,并为那些是格式化的时间戳。但同样,这仅在该属性的值是有效数字时才有效(当然,您需要调整与字符串文字 'timestamp' 的比较以使用正确的属性名称)

【讨论】:

  • 现在我收到以下错误:错误:整数输入语法无效:“假”
  • 我刚刚想通了,attribute_value 不仅包含存储为 varchar 的数字。它还包含真、假、人等。所以我需要清理数据库,以便以正确的方式存储东西
  • @kya:查看我的编辑。如果您知道特定属性名称仅包含有效数字,则可以使用 CASE 语句来处理。
【解决方案3】:

试试这个。但我不确定您是否可以将其转换为时间戳。转换为时间戳时,您可能会遇到另一个错误。还是试试吧。

    SELECT cu.user_name, cu.created_date, cu.updated_date, 
    cu.email_address, cua.attribute_name, cua.attribute_value,
    (select to_char(to_timestamp(cast(cua.attribute_value as double precision) / 1000), 'yyyy-mm-dd HH24:MI:SS')) AS Issue_Update
    FROM cwd_user cu
    INNER JOIN cwd_user_attribute cua ON cu.id = cua.user_id
    WHERE cu.user_name LIKE 'perter%'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多