一种SQL查询,它将一行中的聚合值和非聚合值组合在一起

时间:2015-10-26 22:13:40

标签: sql oracle

以下查询为我提供了我需要的信息,但我希望它能够更进一步。在底部的表格中(仅显示字段的子集),我想以不寻常的方式按cust_line进行分组(至少对我来说这是不寻常的)。

让我们看一下cust_line为2的项目作为例子。我希望这些由一行而不是5代表。对于这一行,我想选择除cust_part =" GROUPINVC"的价格字段以外的所有字段。对于总字段,我希望它总和(总计)为new_total'对于价格,我希望它是new_total / qty_invoiced,其中qty_invoiced是cust_part =" GROUPINV"。

的行上的值。

我要求的是完全荒谬的吗?它甚至可能吗?我没有在SQL方面取得进步,所以它也可能很容易,我只是不知道如何处理它。我想过使用'分区'但我无法想象如何让它工作,因为我认为它仍会返回5行,我只想要1行。

我也用类似的标题查看了这些问题,但并不是我真正想要的:

SQL query that returns aggregate AND non aggregate results

Combined aggregated and non-aggregate query in SQL

SELECT L.CUST_LINE, I.LINE_NO, I.ORDER_NO, I.STAGE, I.ORDER_LINE_POS, I.CUST_PART, 
I.LINE_ITEM_NO, I.QTY_INVOICED, I.CUST_DESC, I.DESCRIPTION, I.SALE_UNIT_PRICE, I.PRICE_TOTAL,
I.INVOICE_NO, I.CUSTOMER_PO_NO, I.ORDER_NO, I.CUSTOMER_NO, I.CATALOG_DESC, I.ORDER_LINE_NOTES
FROM 
  (SELECT CUST_LINE, ORDER_NO, LINE_NO
   FROM CUSTOMER_ORDER_LINE
   GROUP BY CUST_LINE, ORDER_NO, LINE_NO
   ) L
INNER JOIN CUSTOMER_ORDER_IVC_REP I
ON I.ORDER_NO = L.ORDER_NO
WHERE RESULT_KEY = 999999
AND I.LINE_NO = L.LINE_NO
ORDER BY L.CUST_LINE;

| cust_line | line_no | cust_part | qty_invoiced | cust_desc | price | total |
|         1 |       4 |      ...  |            1 |       ... |    55 |   55  |
|         2 |       1 | GROUPINV  |            1 | some part |     0 |    0  |
|         2 |       6 |      ...  |            3 |       ... |     0 |    0  |
|         2 |       2 |      ...  |            1 |       ... |     0 |    0  |
|         2 |       3 |      ...  |            1 |       ... |     0 |    0  |
|         2 |       7 |      ...  |            2 |       ... |    10 |   20  |
|         3 |       7 |      ...  |            1 |       ... |    67 |   67  |

1 个答案:

答案 0 :(得分:0)

您可以使用分析函数计算结果集中多行的总数,然后过滤掉您不想要的行。

为了简洁起见,省略了所有额外的列:

SELECT cust_line, qty_invoiced, order_total/qty_invoiced AS price
FROM (
  SELECT l.cust_line, qty_invoiced,
    SUM(total) OVER (PARTITION BY l.cust_line) AS order_total,
    COUNT(cust_line) OVER (PARTITION BY l.cust_line) AS group_count
  FROM
  (SELECT CUST_LINE, ORDER_NO, LINE_NO
   FROM CUSTOMER_ORDER_LINE
   GROUP BY CUST_LINE, ORDER_NO, LINE_NO
   ) L
  INNER JOIN CUSTOMER_ORDER_IVC_REP I
  ON I.ORDER_NO = L.ORDER_NO
  WHERE RESULT_KEY = 999999
  AND I.LINE_NO = L.LINE_NO
)
WHERE ( cust_part = 'GROUPINV' OR group_count = 1 )
ORDER BY cust_line

我在PARTITION BY条款中猜测你想要什么;这基本上是GROUP BY,仅适用于SUM函数。不确定您是否还想在分区中使用order_no

诀窍是选择内部查询中的所有行,并在它们之间应用SUM;然后在最外面的查询中过滤掉你不感兴趣的行。