SQL:两列分区

时间:2018-04-26 13:52:26

标签: sql oracle window-functions

我有以下表格:

let $t := fn:doc(“MEN.xml”)
return 
    for $a in (“appearance”, “objectification”)
    return
        for $sex in (“female”, “male”)
        return
           fn:count($t/thread/comment[@gender = $sex]/*[fn:local-name(.) = $a])

我希望将两列(No1,No2)的分区相加,但是当两列中的值发生变化时,它也应该分组。例子是:AB = BA

这是我的预期结果:

---------------------
| No1 | No2  | Amount
---------------------
| A   |  B   |    10 |
| C   |  D   |    20 |
| B   |  A   |    30 |
| D   |  C   |    40 |
---------------------

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

使用leastgreatest

select no1,no2,sum(amount) over(partition by least(no1,no2),greatest(no1,no2)) as total
from tbl

答案 1 :(得分:0)

只是一个想法:

Const EM_1 = "I6,I8,B12:I12,B16:I16,I18,I28,I30,I32,I36,I38,I40,I44,I46,I48,"
Const EM_2 = "I56,I58,I60,I66,I68,I70,I72,I74,I78,I80,I82,I88,I96,I98,"
Const EM_3 = "B104:I104,I106,B111:I111,B115:I115,L6:Z120"

Const EM = EM_1 & EM_2 & EM_3   'Required ranges on Sheet "Engagement Form"
Const DP = "B9:B19"             'Required ranges on Sheet "Data Protection Crib Sheet"
Const AA = "B9:B44"             'Required ranges on Sheet "A & A Crib Sheet"
Const GC = "B9:B17"             'Required ranges on Sheet "Governance Crib Sheet"
Const S1 = "A1:A2, B3:B5"       '<--- New sheet, with new equired ranges (on Sheet1)

Dim wsEM As Worksheet, wsDP As Worksheet, wsAA As Worksheet, wsGC As Worksheet
Dim wsS1 As Worksheet           '<--- New sheet

Set wsEM = ThisWorkbook.Worksheets("Engagement Form")     'Reference to the sheet
Set wsDP = ThisWorkbook.Worksheets("Data Protection Crib Sheet")
Set wsAA = ThisWorkbook.Worksheets("A & A Crib Sheet")
Set wsGC = ThisWorkbook.Worksheets("Governance Crib Sheet")
Set wsS1 = ThisWorkbook.Worksheets("Sheet1") '<--- New sheet

Dim rng As Variant, invalid As Long

For Each rng In Array(wsEM.Range(EM), wsDP.Range(DP), wsAA.Range(AA), wsGC.Range(GC), _
                      wsS1.Range(S1))
    invalid = invalid + (rng.Cells.Count - Application.WorksheetFunction.CountA(rng))
Next

If invalid > 0 Then MsgBox "Please fill out all " & invalid & " cells"

输出 - 你可以用任何vlue替换nulls(空):

WITH test_data AS
(
SELECT 'A' no1, 'B' no2, 10 amt FROM dual
UNION ALL
SELECT 'C', 'D', 20 FROM dual
UNION ALL
SELECT 'B', 'A', 30 FROM dual
UNION ALL
SELECT 'D', 'C', 40 FROM dual
)
SELECT NVL(no1, break_group) no1, no2, total --, grp1, grp2, break_group 
  FROM
(
SELECT no1, no2, total
     , grouping(no1) grp1
     , grouping(no2) grp2
     , LAG(no1, 2) OVER (PARTITION BY total ORDER BY no1)||LAG(no1) OVER (PARTITION BY total ORDER BY no1) break_group
  FROM
( -- Vamsi Prabhala query --
select no1, no2
     , sum(amt) over(partition by least(no1,no2),greatest(no1,no2)) as total
from test_data
)
GROUP BY ROLLUP (total, no1, no2)
HAVING grouping(no1) + grouping(no2) = 0
OR grouping(no1) + grouping(no2) = 2
AND total IS NOT NULL
)
/