【问题标题】:Is it possible to BREAK ON a column in addition to the one specified in SQL*Plus?除了 SQL*Plus 中指定的列之外,是否可以对列进行 BREAK ON?
【发布时间】:2009-06-11 20:17:46
【问题描述】:

这个很难解释,所以我会在使用示例后尝试展示我的意思。请注意,我不是在询问是否可以在 BREAK 语句中使用多个列——我知道可以。

假设我有如下查询:

SELECT  invoice_no, invoice_date, vendor, account, amount
FROM    invoice
ORDER   BY vendor, invoice_no, account

假设结果集是:

INVOICE_NO INVOICE_DATE VENDOR  ACCOUNT AMOUNT
---------- ------------ ------- ------- ------
0001       30-JAN-2009  Alpha   1000     50.00
0003       30-JAN-2009  Alpha   1000    125.00
0003       30-JAN-2009  Alpha   3000     33.33
0006       02-FEB-2009  Alpha   2000     40.00
0005       31-JAN-2009  Bravo   1000     40.00
0002       30-JAN-2009  Charlie 2000    120.75
0002       30-JAN-2009  Charlie 3000      5.00
0004       30-JAN-2009  Charlie 1000    900.50

所以你可以看到有些供应商有多个发票,有些发票有多个帐户。

要隐藏重复的供应商名称和发票编号,我可以使用 SQL*Plus 的 BREAK 命令,如下所示:

BREAK ON vendor ON invoice_no

产生这个结果集:

INVOICE_NO INVOICE_DATE VENDOR  ACCOUNT AMOUNT
---------- ------------ ------- ------- ------
0001       30-JAN-2009  Alpha   1000     50.00
0003       30-JAN-2009          1000    125.00
           30-JAN-2009          3000     33.33
0006       02-FEB-2009          2000     40.00
0005       31-JAN-2009  Bravo   1000     40.00
0002       30-JAN-2009  Charlie 2000    120.75
           30-JAN-2009          3000      5.00
0004       30-JAN-2009          1000    900.50

到目前为止,一切都很好。我还想隐藏重复的发票日期,以便只显示每张发票的第一个日期。但是,如果我使用这个命令:

BREAK ON vendor ON invoice_no ON invoice_date

它会走得太远并隐藏发票 0003 和 0004 的日期,因为它们与各自供应商以前的发票相同:

INVOICE_NO INVOICE_DATE VENDOR  ACCOUNT AMOUNT
---------- ------------ ------- ------- ------
0001       30-JAN-2009  Alpha   1000     50.00
0003                            1000    125.00
                                3000     33.33
0006       02-FEB-2009          2000     40.00
0005       31-JAN-2009  Bravo   1000     40.00
0002       30-JAN-2009  Charlie 2000    120.75
                                3000      5.00
0004                    Charlie 1000    900.50

我真正想要的是类似以下的命令语法(我编造了术语AND):

BREAK ON vendor ON invoice_no AND invoice_date

目的是,每当它在 invoice_no 中断时,也会在 invoice_date 中断(因为我知道一个发票号不能有两个发票日期):

INVOICE_NO INVOICE_DATE VENDOR  ACCOUNT AMOUNT
---------- ------------ ------- ------- ------
0001       30-JAN-2009  Alpha   1000     50.00
0003       30-JAN-2009          1000    125.00
                                3000     33.33
0006       02-FEB-2009          2000     40.00
0005       31-JAN-2009  Bravo   1000     40.00
0002       30-JAN-2009  Charlie 2000    120.75
                                3000      5.00
0004       30-JAN-2009  Charlie 1000    900.50

现在可以正确显示发票 0003 和 0004 的日期。

有什么方法可以在 SQL*Plus 中实现这一点吗?

【问题讨论】:

  • 你能看看这个link

标签: reporting sqlplus


【解决方案1】:

你想要这样的东西:

列 DUMMY NOPRINT
BREAK ON DUMMY ON vendor ON invoice_no
SELECT CONCAT (vendor, invoice_no) DUMMY, invoice_no, invoice_date, vendor, account,amount
来自发票
ORDER BY vendor, invoice_no, account

您将column DUMMY 设置为未打印的位置 然后在您的选择中将其定义为您需要检查的两个字段的串联。

DUMMY 只是一个任意名称,但通常用于需要计算但不显示它的情况

额外的“ON vendor ON invoice_no”允许您控制那些与 DUMMY 中断分开的列上的 dup。同样,您可以使用DUMMY 计算得到总数等。

【讨论】:

    【解决方案2】:

    您可以BREAK ON 一个表达式,因此通过将感兴趣的字段转换为字符串并将它们与|| 连接,您应该能够组合一个表达式,让您可以打破“它们的两个值”。

    【讨论】:

    • 我想知道这一点。您的意思是我应该将查询更改为以“SELECT invoice_no || ' ' || TO_CHAR(invoice_date) invoice_no_date,...”开头,然后对 invoice_no_date 列别名进行 BREAK,还是有更巧妙的方法不改变查询?
    • 我相信(但手头没有 SQL*Plus 可以测试)您可以“BREAK ON (invoiceno||TO_CHAR(invoice_date))”——也就是说,BREAK ON 可以使用表达式,不仅仅是一个列名。
    • 我试过了,但是没有用。通过查看它,我不确定 SQL*Plus 如何知道根据该表达式的内容停止打印这两列的重复项。从我可以从文档中收集到的信息来看,如果在 SELECT 语句中使用相同的表达式,您似乎只能使用表达式,但在这种情况下,列别名似乎是更简单的方法。
    • 这是 SQLPlus 用户指南和参考 v10.2 中的解释:“您可以使用涉及一个或多个表列的表达式或在 SQL SELECT 中分配给报告列的别名或 SQLPlus COLUMN 命令。如果在 BREAK 命令中使用表达式,则必须输入与在 SELECT 命令中完全相同的 expr。例如,如果 SELECT 命令中的表达式是 a+b,则不能在 BREAK 命令中使用 b+a 或 (a+b) 来引用 SELECT 命令中的表达式。" (download.oracle.com/docs/cd/B19306_01/server.102/b14357/…)
    【解决方案3】:

    SQL*Plus 似乎无法解决问题。每当发票编号为空白时,我最终使用sed 删除发票日期:

    sed -re 's/^( {11})[0-9A-Z-]{11}(.+)$/\1           \2/'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多