【问题标题】:Column Concatenation in Oracle [closed]Oracle中的列连接[关闭]
【发布时间】:2019-08-14 05:59:44
【问题描述】:

我正在尝试将这三列合并为一列,但出现错误,有什么帮助吗?

 WITH ABC AS
    (select tsk.task_number || ' / '|| tsk.task_status|| ' / '|| tsk.summary,
            CSI.creation_date AS creation_date
    FROM csf_ct_task_assignments tsa,CSF_DEBRIEF_HEADERS db, csf_ct_tasks tsk ,CSI_ITEM_INSTANCES csi
    where 1=1
    and tsk.customer_product_id = csi.instance_id 
    and tsk.INCIDENT_CUSTOMER_ID = csi.OWNER_PARTY_ID
    and tsa.Task_Assignment_Id=db.Task_Assignment_Id(+)
    and tsk.task_id = tsa.task_id (+)
    and tsk.task_type like '%Termination%'
    and tsk.task_status_id<>7
    and (SELECT  actual_shipment_date
    FROM oe_order_lines_all
    WHERE line_id= csi.last_oe_order_line_id)
    <= tsk.creation_date
    and rownum=1
    ) AS termination_call_dtls,

[错误]: Execution (14: 74): ORA-00936: missing expression

【问题讨论】:

  • WITH 子句语法为with abc as ( ... ) select * from abc;。所以 Oracle 期望在右括号后使用 SELECT,但您却给了它 AS termination_call_dtls,。
  • 您迫切需要摆脱使用逗号分隔表的旧 SQL 语法。

标签: sql oracle string-concatenation


【解决方案1】:

但我想在termination_call_dtls 中连接这些列!!

正如@APC 所提到的,问题在于您试图为WITH 块设置别名。不清楚您是否需要子查询分解;你可以这样做:

select tsk.task_number || ' / '|| tsk.task_status|| ' / '|| tsk.summary AS termination_call_dtls,
  CSI.creation_date AS creation_date
FROM csf_ct_task_assignments tsa,CSF_DEBRIEF_HEADERS db, csf_ct_tasks tsk ,CSI_ITEM_INSTANCES csi
where 1=1
and tsk.customer_product_id = csi.instance_id 
and tsk.INCIDENT_CUSTOMER_ID = csi.OWNER_PARTY_ID
and tsa.Task_Assignment_Id=db.Task_Assignment_Id(+)
and tsk.task_id = tsa.task_id (+)
and tsk.task_type like '%Termination%'
and tsk.task_status_id<>7
and (SELECT  actual_shipment_date
FROM oe_order_lines_all
WHERE line_id= csi.last_oe_order_line_id)
<= tsk.creation_date
and rownum=1

在第一行使用termination_call_dtls 作为列 别名。

正如 cmets 中也提到的,您应该考虑使用现代连接语法,而不是您现在拥有的旧的和仅适用于 Oracle 的语法;并且子查询作为另一个连接可能会更好,例如:

select tsk.task_number || ' / '|| tsk.task_status|| ' / '|| tsk.summary as termination_call_dtls,
  csi.creation_date
from csf_ct_tasks tsk
join csi_item_instances csi on csi.instance_id = tsk.customer_product_id
and csi.owner_party_id = tsk.incident_customer_id
join oe_order_lines_all oola on oola.line_id = csi.last_oe_order_line_id
and ools.actual_shipment_date <= tsk.creation_date
left join csf_ct_task_assignments tsa on tsa.task_id = tsk.task_id
left join csf_debrief_headers db on db.task_assignment_id = tsa.task_assignment_id
where tsk.task_type like '%Termination%'
and tsk.task_status_id != 7
and rownum = 1

如果需要,无论哪种方式,您仍然可以将查询用作 CTE - 如果它是比您展示的更大、更复杂的查询的一部分。

不清楚为什么你有csf_ct_task_assignments 或csf_debrief_headers 的(外部)连接,因为无论如何你都不使用这些表中的任何列。这些连接可能只是被删除。

您还应该知道and rownum = 1 将返回一个不确定的行,假设您在没有它的情况下获得多行。通常你会有一个包含order by 子句的内联视图,然后应用rownum 过滤器来限制结果,例如(猜你想要最早的创建日期):

select termination_call_dtls, creation_date
from (
  select tsk.task_number || ' / '|| tsk.task_status|| ' / '|| tsk.summary as termination_call_dtls,
    csi.creation_date
  from csf_ct_tasks tsk
  join csi_item_instances csi on csi.instance_id = tsk.customer_product_id
  and csi.owner_party_id = tsk.incident_customer_id
  join oe_order_lines_all oola on oola.line_id = csi.last_oe_order_line_id
  and ools.actual_shipment_date <= tsk.creation_date
  where tsk.task_type like '%Termination%'
  and tsk.task_status_id != 7
  order by csi.creation_date
)
where rownum = 1

从 12c 开始,还有其他机制可以稍微简化这一点。或者使用聚合:

select tsk.task_number || ' / '|| tsk.task_status|| ' / '|| tsk.summary as termination_call_dtls,
  min(csi.creation_date) as creation_date
from csf_ct_tasks tsk
join csi_item_instances csi on csi.instance_id = tsk.customer_product_id
and csi.owner_party_id = tsk.incident_customer_id
join oe_order_lines_all oola on oola.line_id = csi.last_oe_order_line_id
and ools.actual_shipment_date <= tsk.creation_date
where tsk.task_type like '%Termination%'
and tsk.task_status_id != 7
group by tsk.task_number, tsk.task_status, tsk.summary

【讨论】:

    【解决方案2】:

    您的查询中的串联没有问题。

    您需要将WITH 与SELECT 一起使用,如下所示:

    WITH ABC AS (
        SELECT
            TSK.TASK_NUMBER
            || ' / '
            || TSK.TASK_STATUS
            || ' / '
            || TSK.SUMMARY as termination_call_dtls,
            CSI.CREATION_DATE   AS CREATION_DATE
        FROM
            CSF_CT_TASK_ASSIGNMENTS TSA,
            CSF_DEBRIEF_HEADERS DB,
            CSF_CT_TASKS TSK,
            CSI_ITEM_INSTANCES CSI
        WHERE
            1 = 1
            AND TSK.CUSTOMER_PRODUCT_ID = CSI.INSTANCE_ID
            AND TSK.INCIDENT_CUSTOMER_ID = CSI.OWNER_PARTY_ID
            AND TSA.TASK_ASSIGNMENT_ID = DB.TASK_ASSIGNMENT_ID (+)
            AND TSK.TASK_ID = TSA.TASK_ID (+)
            AND TSK.TASK_TYPE LIKE '%Termination%'
            AND TSK.TASK_STATUS_ID <> 7
            AND (
                SELECT
                    ACTUAL_SHIPMENT_DATE
                FROM
                    OE_ORDER_LINES_ALL
                WHERE
                    LINE_ID = CSI.LAST_OE_ORDER_LINE_ID
            ) <= TSK.CREATION_DATE
            AND ROWNUM = 1
    )
    -- YOU ARE MISSING FOLLOWING SELECT STATEMENT
    SELECT
        *
    FROM
        ABC;
    

    干杯!!

    【讨论】:

    • 但我想在termination_call_dtls 中连接这些列!!
    • 所以你对列的名称感到烦恼然后看看我更新的答案
    猜你喜欢
    • 2012-07-04
    • 2011-04-11
    • 2011-10-10
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2018-09-09
    • 2014-09-11
    相关资源
    最近更新 更多