【问题标题】:How to do a join in Oracle tables?如何在 Oracle 表中进行联接?
【发布时间】:2018-03-20 16:40:06
【问题描述】:

我正在尝试帮助一位同事对两个 oracle 表进行内部联接,以便他可以在报表上构建特定图表。

我没有 Oracle 经验,只有 SQL Server,并且得到了看起来合适的语句,但不起作用。

SELECT concat(concat(month("a.timestamp"),','),day("a.timestamp")) as monthDay
    , min("a.data_value") as minTemp
    , max("a.data_value") as maxTemp
    , "b.forecast" as forecastTemp
    , "a.timestamp" as date
FROM table1 a
WHERE "a.category" = 'temperature'
GROUP BY concat(concat(month("timestamp"),','),day("timestamp"))
INNER JOIN (SELECT "forecast"
           , "timestamp"
        FROM table2
        WHERE "category" = 'temperature') b
ON "a.timestamp" = "b.timestamp"

出于某种原因,它不喜欢我的别名。它不喜欢由于某种原因没有引号。

此外,当我使用完整评分的名称时,它仍然失败,因为:

ORA-00933 SQL command not properly ended

【问题讨论】:

  • 将组移到末尾
  • 还有在哪里
  • 样本数据和期望的结果会有所帮助。
  • 您已将别名放在双引号内;双引号表示里面的文本应该被认为是区分大小写的标识符。正确的语法应该是:select a."timestamp" from table1 a;。请注意,如果您(无论出于何种原因)决定使用区分大小写的别名,则需要将其单独引用到任何列,例如select "a"."timestamp" from table1 "a";。如果您对表有任何控制权,请不要使用区分大小写的标识符创建它们;那样就是疯狂! *{;-)

标签: sql oracle inner-join etl


【解决方案1】:

查询的顺序应该是

SELECT
FROM
INNER JOIN
WHERE
GROUP BY

如下

SELECT concat(concat(month("a.timestamp"),','),day("a.timestamp")) as monthDay
    , min("a.data_value") as minTemp
    , max("a.data_value") as maxTemp
    , "b.forecast" as forecastTemp
    , "a.timestamp" as date
FROM table1 a
INNER JOIN (SELECT "forecast"
       , "timestamp"
      FROM table2
      WHERE "category" = 'temperature') b
ON "a.timestamp" = "b.timestamp"
WHERE "category" = 'temperature'
GROUP BY concat(concat(month("timestamp"),','),day("timestamp"))

【讨论】:

    【解决方案2】:

    在大量尝试中,这里还有一个。

    • table2 可以移出子查询;也将它与 table1 的类别一起加入
    • 请注意,所有非聚合列(来自 SELECT)都必须包含在 GROUP BY 子句中。似乎a.timestamp 包含的信息不仅仅是 月和日 - 如果是这样,它可能会破坏整个结果集,因为数据不会按 月日分组>,但在整个日期之前 - 如有必要,请考虑将其从 SELECT 中删除

    SELECT TO_CHAR(a.timestamp,'mm.dd') monthday,
          MIN(a.data_value) mintemp,
          MAX(a.data_value) maxtemp,
          b.forecast forecasttemp,
          a.timestamp c_date
    FROM table1 a
    JOIN table2 b ON a.timestamp = b.timestamp
                 AND a.category = b.category
    WHERE a.category = 'temperature'
    GROUP BY TO_CHAR(a.timestamp,'mm.dd'),
             b.forecast,
             a.timestamp;
    

    【讨论】:

    • 绝对是最惯用的 Oracle
    【解决方案3】:

    select 的正确(简化)语法是

    SELECT <columns>
    FROM table1 <alias>
       JOIN table2 <alias> <join_condition>
    WHERE <condition>
    GROUP BY <group by columns>
    

    【讨论】:

      【解决方案4】:

      你做错了。使用子查询:

      SELECT c.*,  b.`forecast` as forecastTemp
      FROM
      (SELECT concat(concat(month(a.`timestamp`),','),day(a.`timestamp`)) as monthDay
          , min(a.`data_value`) as minTemp
          , max(a.`data_value`) as maxTemp
          , a.`timestamp` as date
      FROM table1 a
      WHERE `category`='temperature'
      GROUP BY concat(concat(month(`timestamp`),','),day(`timestamp`))) c
      INNER JOIN (SELECT `forecast`
                 , `timestamp`
              FROM table2
              WHERE `category` = 'temperature') b
      ON c.`timestamp` = b.`timestamp`;
      

      【讨论】:

        【解决方案5】:

        除了其他答案提到的组件顺序(wherejoin 等之后),您还需要删除所有双引号字符。在 Oracle 中,这些会覆盖标准命名规则,因此 "a.category" 仅在您的表实际上有一个名为 "a.category" 的列时才有效,例如

        create table demo ("a.category" varchar2(10));
        
        insert into demo ("a.category") values ('Weird');
        
        select d."a.category" from demo d;
        

        很少需要这样做。

        【讨论】:

          【解决方案6】:

          查询应该如下所示:

          SELECT to_char(a.timestamp, 'MM-DD') as monthDay,
                 min(a.data_value) as minTemp,
                 max(a.data_value) as maxTemp,
                 b.forecast as forecastTemp
          FROM table1 a JOIN
               table2 b
               ON a.timestamp = b.timestamp and b.category = 'temperature'
          WHERE a.category = 'temperature'
          GROUP BY to_char(timestamp, 'MM-DD'), b.forecast;
          

          我不是 100% 确定这是您想要的。您的查询有很多问题和复杂性:

          • FROM 子句中不需要子查询。
          • 您可以使用to_char() 代替更复杂的日期字符串处理。
          • group by 未包含所有相关字段。
          • 不要使用双引号,除非真的非常需要。

          【讨论】:

          • 大概应该删除所有 OP 的双引号,除非其中一个表实际上有名为 "a.data_value" 等的列,在这种情况下,它们应该加上前缀,例如a."a.data_value".
          猜你喜欢
          • 2011-04-12
          • 2012-03-13
          • 2010-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-22
          • 2011-05-07
          相关资源
          最近更新 更多