如何执行double to_char?

时间:2016-11-15 17:47:52

标签: sql oracle

当我尝试此查询时:

SELECT EQUIPA,COUNT(*) TOTAL, to_char(DATAD, 'YY.MM.DD') Data FROM
  (
        SELECT EQUIPA, to_char(OS_DATACONCLUSAO,'YY.MM.DD HH24') DATAD

        FROM OS_CRM_DB_FINAL

        WHERE USERFECHO IS NOT null AND ( EQUIPA = 'AAA') AND (to_char(OS_DATACONCLUSAO,'YY.MM.DD HH24') >= '16.11.03 17:07') AND (to_char(OS_DATACONCLUSAO,'YY.MM.DD HH24') <= '16.11.15 17:07')

        ORDER BY DATAD DESC
  ) GROUP BY EQUIPA, Data
;

我收到了这个错误:

  
      
  1. 00000 - &#34;无效的号码&#34;
  2.   

我做错了什么?谢谢

2 个答案:

答案 0 :(得分:1)

我没有检查内部查询的正确性 - 您没有提供测试数据,我也不会创建自己的测试数据。但是:如果它是正确的,你需要做的就是在内部查询中选择OS_DATACONCLUSAO(&#34;子查询&#34;),而不是它的字符串表示。 (您仍然使用WHERE子句中的字符串表示,而不是SELECT中的字符串表示。)

试一下,看看它是否有效。然后我们可以讨论WHERE子句中的内容;它可能不正确(日期不应该作为字符串进行比较),即使它是正确的,也是非常低效的。要正确比较,您应该将您要比较的字符串转换为to_date()的日期,而不是将日期值转换为字符串。

答案 1 :(得分:1)

您尝试按data分组,ORA-00904: "DATA": invalid identifier是在同一查询级别中定义的列别名,因此会生成SELECT EQUIPA, COUNT(*) TOTAL, substr(DATAD, 1, 8) Data FROM ( ... -- original inner query ) GROUP BY EQUIPA, substr(DATAD, 1, 8)

您正在将日期转换为字符串(由于某种原因有两位数年份)并与另一个字符串进行比较,这无论如何都不是一个好主意 - 如果日期列已编入索引,则将其转换为字符串可防止用于比较的索引,它通常更有意义,并且比较原始数据类型更有效。但是这些字符串最终会有不同的格式 - 一个有分钟,另一个没有。

您的内部查询是将日期转换为字符串,并对结果进行排序;这表明这是您现在正在尝试总结的现有查询。 order-by毫无意义,不会影响外部查询中结果的顺序。

如果您真的想要坚持内部查询中的字符串,只要日期格式合适,您就可以使用子字符串,并在组中使用该子字符串:

SELECT EQUIPA, COUNT(*) TOTAL,
    to_char(to_date(DATAD, 'YY.MM.DD HH24'), 'YY.MM.DD') Data FROM
  (
    ... -- original inner query
  ) GROUP BY EQUIPA, to_date(DATAD, 'YY.MM.DD HH24')

或转换回日期,然后再转换为字符串,并在group-by中使用转换后的日期,这比您需要做的工作多,但逻辑上是您最初尝试做的事情:

SELECT EQUIPA, COUNT(*) TOTAL, to_char(TRUNC(OS_DATACONCLUSAO), 'YY.MM.DD') Data
FROM OS_CRM_DB_FINAL
WHERE USERFECHO IS NOT null
AND EQUIPA = 'AAA'
AND OS_DATACONCLUSAO >= TO_DATE('2016.11.03 17:07:00', 'YYYY.MM.DD HH24:MI:SS')
AND OS_DATACONCLUSAO <= TO_DATE('2016.11.15 17:07:00', 'YYYY.MM.DD HH24:MI:SS')
GROUP BY EQUIPA, TRUNC(OS_DATACONCLUSAO)
ORDER BY EQUIPA, TRUNC(OS_DATACONCLUSAO) DESC

或更改内部查询以返回原始日期而不是字符串;虽然内部查询根本不需要:

data

我已更改过滤器,将日期比较为日期而非字符串。日期仅在最后时刻转换为字符串以供显示。另请注意,我已按截短日期排序(默认情况下,它会为您提供时间设置为午夜的日期)。您可以在order-by(但不是其他地方)中使用sys.stdout.flush()列别名,在这种情况下,它可以正常使用;但如果您在结果集中格式化日期不同,例如MM / DD / YYYY您想按日期而不是字符串订购。