2

这是背后的故事。

我正在尝试生成包含特定人员正确佣金值的交易列表。不是每个人都有资格获得佣金,但那些在佣金表中有条目的人可以指定他们赚取的发票项目、项目子类、项目类别和/或默认佣金值。

我的问题在于佣金表的构建方式使得选择非常困难,如下所示:

佣金表

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:
如果交易包括:

  • 发票项目编号:1234
  • 子类:FOP
  • inv类:NTR

SQL 应该匹配 subclassid ("FOP") 而不是 invclass ("NTR") 导致佣金为 5.0 而不是 0.0

例如 2:如果交易不包含匹配项:

  • 发票项目编号:1234
  • 子类:STR
  • 类:BLA

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        

我以前从未遇到过设计如此奇怪且没有可供选择的主键的表。

对于你们可以提供的任何帮助,我将不胜感激!

4

2 回答 2

1

一种方法:分别链接到每种类型的佣金,并使用 case 子句来确定哪个是最具体的可用 - 如下所示:

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'
于 2013-06-16T17:11:54.790 回答
0

left outer join我认为你可以通过 a和聚合得到你想要的:

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应该在发票列表中获取所有可能的匹配项。窗口函数计算匹配的最小序列号。然后这用于在原始数据中为每个项目选择一行。

于 2013-06-16T17:45:29.670 回答