MySQL:基于稍后联接的表的联接条件

时间:2018-08-24 09:20:21

标签: mysql sql

SELECT
    p.Sku,
    p.Barcode,
    s.AmountIncl,

    CASE
        WHEN SUM(dl.Qty) IS NULL THEN 0
        ELSE SUM(dl.Qty)
    END AS Qty,

    CASE
        WHEN SUM(dl.SubTotal) IS NULL THEN 0
        ELSE SUM(dl.SubTotal)
    END AS SubTotal

FROM
    Product AS p

        LEFT JOIN
    DocumentLine AS dl ON p.Sku = dl.Sku

        LEFT JOIN
    Document AS d ON dl.DocumentId = d.DocumentId
        AND d.DocumentTypeEnum = 'Order'
        AND d.PaymentStatusEnum = 'Paid'

        LEFT JOIN
    StandardPrice AS s ON p.ProductId = s.ProductId

WHERE
    p.Barcode IS NOT NULL

GROUP BY p.Sku

我正在尝试获取Sku对已实际支付的订单进行分组的“数量”和“小计”数字。 可以在文档表中使用条件(d.DocumentTypeEnum ='Order'和d.PaymentStatusEnum ='Paid')来标识这些订单。 财务数据(数量和小计)位于DocumentLine中。

如何在DocumentLine表中排除链接到文档(通过DocumentId链接)的订单/数据,其中DocumentTypeEnum不是“订单”,而PaymentStatusEnum不是“已付费”?

此刻,DocumentLine包括已付款订单,失败订单,未付款订单,待处理订单,购物车等。因此,“数量”和“小计”数据比我们实际出售/生成的数据要高得多。

注意:我仍然想显示所有SKU WHERE条码不为空。因此,如果DocumentLine中没有Sku的日期,那么“数量”和“小计”值应为0?

我正在MySQL中查询

样本数据

Product
Sku | Barcode
1   | A
2   | B
3   | 
4   | C
5   |
6   | D

DocumentLine
Sku | Qty | SubTotal | DocumentId
1   | 1   | 100      | 123
2   | 1   | 150      | 124
4   | 2   | 400      | 125
6   | 1   | 120      | 128
1   | 2   | 200      | 129
4   | 1   | 200      | 131
3   | 1   | 600      | 127

Document
DocumentId | DocumentTypeEnum | PaymentStatusEnum
123        | Order            | Paid
124        | Cart             | NotApplicable
125        | Order            | Pending
126        | Cart             | NotApplicable
127        | Cart             | NotApplicable
128        | Order            | Failed
129        | Order            | Paid
130        | Cart             | NotApplicable
131        | Order            | Paid

Result:
Sku | Barcode | AmountIncl | Qty | SubTotal
1   | A       | 50         | 3   | 300
2   | B       | 60         | 0   | 0
4   | C       | 40         | 1   | 200
6   | D       | 80         | 0   | 0

3 个答案:

答案 0 :(得分:1)

    SELECT p.Sku, p.Barcode, s.AmountIncl, 
                CASE WHEN SUM(doc.Qty) IS NULL THEN 0
                ELSE SUM(doc.Qty)
            END AS Qty,
            CASE WHEN SUM(doc.SubTotal) IS NULL THEN 0
                ELSE SUM(doc.SubTotal)
            END AS SubTotal
        FROM Product AS p
           LEFT JOIN (Select dl.sku as sku, dl.qty as qty, dl.subtotal as subtotal 
               from DocumentLine dl, Document d where dl.DocumentId = d.DocumentId
              AND d.DocumentTypeEnum = 'Order' AND d.PaymentStatusEnum = 'Paid') AS doc 
              ON p.Sku = doc.Sku
           LEFT JOIN StandardPrice AS s ON p.ProductId = s.ProductId

        WHERE p.Barcode IS NOT NULL
GROUP BY p.Sku

答案 1 :(得分:1)

您可以尝试一下。只需基于LEFT JOIN表使用Product并过滤要获取的Barcode。具有条件聚合功能来实现。

CREATE TABLE Product(
   Sku INT,
   Barcode VARCHAR(10)
);



INSERT INTO Product VALUES (1,'A');
INSERT INTO Product VALUES (2,'B');
INSERT INTO Product VALUES (3,'');
INSERT INTO Product VALUES (4,'C');
INSERT INTO Product VALUES (5,'');
INSERT INTO Product VALUES (6,'D');


CREATE TABLE DocumentLine(
   Sku INT,
   Qty INT,
  SubTotal INT,
  DocumentId INT
);



INSERT INTO DocumentLine VALUES (1, 1, 100,123);
INSERT INTO DocumentLine VALUES (2, 1, 150,124);
INSERT INTO DocumentLine VALUES (4, 2, 400,125);
INSERT INTO DocumentLine VALUES (6, 1, 120,128);
INSERT INTO DocumentLine VALUES (1, 2, 200,129);
INSERT INTO DocumentLine VALUES (4, 1, 200,131);
INSERT INTO DocumentLine VALUES (3, 1, 600,127);


CREATE TABLE Document(
   Sku INT,
   DocumentTypeEnum VARCHAR(50),
  PaymentStatusEnum VARCHAR(50)
);


INSERT INTO Document VALUES (123 ,'Order',  'Paid');
INSERT INTO Document VALUES (124 ,'Cart',  'NotApplicable');
INSERT INTO Document VALUES (125 ,'Order',  'Pending');
INSERT INTO Document VALUES (126 ,'Cart',  'NotApplicable');
INSERT INTO Document VALUES (127 ,'Cart',  'NotApplicable');
INSERT INTO Document VALUES (128 ,'Order',  'Failed');
INSERT INTO Document VALUES (129 ,'Order',  'Paid');
INSERT INTO Document VALUES (130 ,'Cart',  'NotApplicable');
INSERT INTO Document VALUES (131 ,'Order',  'Paid');

查询1

select 
  p.sku,
  Barcode,
  SUM(case when DocumentTypeEnum = 'Order' and PaymentStatusEnum = 'Paid' then Qty  else 0 end) 'Qty',
  SUM(case when DocumentTypeEnum = 'Order' and PaymentStatusEnum = 'Paid' then SubTotal  else 0 end) 'SubTotal'  
from product p 
left join DocumentLine dl on dl.sku = p.sku
left join Document d on dl.DocumentId = d.Sku
WHERE Barcode <> '' OR Barcode IS NOT NULL
group by p.sku,Barcode

Results

| sku | Barcode | Qty | SubTotal |
|-----|---------|-----|----------|
|   1 |       A |   3 |      300 |
|   2 |       B |   0 |        0 |
|   4 |       C |   1 |      200 |
|   6 |       D |   0 |        0 |

答案 2 :(得分:0)

如果您不希望文档不存在订购和付款,请对文档使用INNER JOIN而不是左键

SELECT p.Sku
  , p.Barcode
  , s.AmountIncl
  , CASE WHEN SUM(dl.Qty) IS NULL THEN 0
        ELSE SUM(dl.Qty)
    END AS Qty
  , CASE WHEN SUM(dl.SubTotal) IS NULL THEN 0
        ELSE SUM(dl.SubTotal)
    END AS SubTotal
FROM Product AS p
LEFT JOIN DocumentLine AS dl ON p.Sku = dl.Sku
INNER JOIN Document AS d ON dl.DocumentId = d.DocumentId
    AND d.DocumentTypeEnum = 'Order'
      AND d.PaymentStatusEnum = 'Paid'
LEFT JOIN StandardPrice AS s ON p.ProductId = s.ProductId
WHERE p.Barcode IS NOT NULL

GROUP BY p.Sku