这是背景故事。
我正在尝试生成一个包含特定人员正确佣金值的交易清单。不是每个人都有资格获得佣金,但是那些在佣金表中有条目的人可以指定他们获得的发票项目,项目子类别,项目类别和/或默认佣金价值。
我的问题在于构建佣金表的方式使得选择起来非常困难,如下所示:
委托表
staffid sequence invoiceitemid subclassid invclassid commission commtype
------- -------- ------------- ---------- ---------- ---------- --------
KH 1 (null) (null) (null) 20.0 1
KH 2 (null) (null) BOA 0.0 2
KH 3 (null) (null) GRO 0.0 2
KH 4 (null) (null) HEA 5.0 2
KH 5 (null) (null) FTP 5.0 2
KH 6 (null) (null) NTR 0.0 2
KH 7 (null) EUK NTR 5.0 2
KH 8 (null) FOP NTR 5.0 2
KH 9 (null) PUR NTR 5.0 2
KH 10 (null) RC NTR 5.0 2
KH 11 (null) (null) MSC 0.0 2
KH 12 (null) (null) MIS 0.0 2
KH 13 1171 (null) (null) 15.8 2
KH 14 1173 (null) (null) 15.2 2
同样,根据COMMISSION表中最具体到最不具体的列,每个事务只应选择一个佣金值。
最具体 - invoiceitemid,subclassid,invclassid - 最不具体
例如1:
如果交易包括:
SQL应该在子类(“FOP”)上匹配,而不是在invclass(“NTR”)上匹配,导致佣金为5.0而不是0.0
例如2: 如果交易不包括匹配:
SQL应匹配invoiceitemid(null),subclassid(null)和invclass(null),导致佣金为20.0
我尝试过什么 使用COALESCE(invoiceitemid,subclassid,invclassid)创建一个包含该记录中最具体项目的列。
但是,在第一个例子中,NTR出现在表格中的FOP之前,因此它首先被错误地匹配。 (见下文)
SELECT COALESCE(invoiceitemid, subclassid, invclassid) AS COMBINE, *
FROM stcomm
WHERE staffid = 'KH'
ORDER BY sequence DESC
COMBINE staffid sequence invoiceitemid subclassid invclassid commission commtype
------- ------- -------- ------------- ---------- ---------- ---------- --------
URN KH 28 (null) URN MSC 0.0 2
6326 KH 27 6326 (null) (null) 0.0 2
6325 KH 26 6325 (null) (null) 0.0 2
6324 KH 25 6324 (null) (null) 0.0 2
6328 KH 24 6328 (null) (null) 0.0 2
5671 KH 23 5671 (null) (null) 20.0 2
5793 KH 22 5793 (null) (null) 20.0 2
4263 KH 21 4263 (null) (null) 0.0 2
5081 KH 20 5081 (null) (null) 20.0 2
3759 KH 19 3759 (null) (null) 0.0 2
4846 KH 18 4846 (null) (null) 0.0 2
SUH KH 17 (null) SUH SUP 5.0 2
SUD KH 16 (null) SUD SUP 5.0 2
SUP KH 15 (null) (null) SUP 0.0 2
1173 KH 14 1173 (null) (null) 15.2 2
1171 KH 13 1171 (null) (null) 15.8 2
为了解决这个问题,我按顺序对序列字段进行了排序,以便首先选择最具体的“FOP”。这确实有效。
如何查询COMMISSION表以在我的交易中显示正确的佣金?
这是我的交易SQL:
SELECT T.staffid, T.invoiceid, T.invoiceitemid, I.subclassid, I.classid, T.quantity, T.invoiceprice
FROM TRANSACT T, INVOITEM I
WHERE T.invoiceitemid = I.invoiceitemid
AND T.staffid = 'KH'
staffid invoiceid invoiceitemid subclassid classid quantity invoiceprice
------- --------- ------------- ---------- ------- -------- ------------
KH 2555.0 04000 FOP NTR 2.00 3.40
KH 3575.0 04000 FOP NTR 7.00 11.90
KH 3981.0 04000 FOP NTR 6.00 10.20
KH 4333.0 04000 FOP NTR 1.00 1.79
KH 6401.0 04000 FOP NTR 5.00 8.95
KH 7863.0 04000 FOP NTR 12.00 21.48
在没有选择主键的情况下,我从未遇到过如此奇怪设计的表。
如果您能提供任何帮助,我将非常感激!
答案 0 :(得分:1)
一种方法:分别链接到每种类型的佣金,并使用案例子句来确定哪种是最具体的 - 如下:
SELECT T.staffid,
T.invoiceid,
T.invoiceitemid,
I.subclassid,
I.classid,
T.quantity,
T.invoiceprice,
case
when iic.staffid is not null then iic.commission
when scc.staffid is not null then scc.commission
when icc.staffid is not null then icc.commission
else def.commission
end Applicable_Commission
FROM TRANSACT T
JOIN INVOITEM I ON T.invoiceitemid = I.invoiceitemid
LEFT JOIN stcomm iic /* Invoice Item Commission */
ON T.staffid = iic.staffid and
T.invoiceitemid = iic.invoiceitemid
LEFT JOIN stcomm scc /* Sub Class Commission */
ON T.staffid = scc.staffid and
T.subclassid = scc.subclassid and
T.invclassid = scc.invclassid
LEFT JOIN stcomm icc /* Inv Class Commission */
ON T.staffid = icc.staffid and
T.invclassid = icc.invclassid and
icc.subclassid is null
LEFT JOIN stcomm def /* Default Commission */
ON T.staffid = iic.staffid and
def.invclassid is null and
def.subclassid is null and
def.invoiceitemid is null
WHERE T.staffid = 'KH'
答案 1 :(得分:0)
我认为你可以通过left outer join
和聚合来获得你想要的东西:
select t.*
from (select t.invoiceid, t.invoiceitemid, t.classid, t.subclassId,
t.quantity, t.invoiceprice, i.*
min(i.sequence) over (partition by t.invoiceid, t.invoiceitemid) as minseq
from TRANSACT t left outer join
INVOITEM i
on (t.staffid = i.staffid or i.staffid is NULL) and
(t.invoiceitemid = i.invoiceitemid or i.invoiceitemid is null) and
(t.classid = i.classid or i.classid is null) and
(t.subclassid = i.subclassid or i.subclassid is null)
where t.staffid = 'KH'
) t
where sequence = minseq or minseq is null
子查询中的join
应该在发票清单中获得所有可能的匹配项。窗口函数计算匹配的最小序列号。然后,这用于在原始数据中为每个项目选择一行。