Only display values of latest available event type

后端 未结 4 1204
南笙
南笙 2020-12-22 06:55

SQL Fiddle:

CREATE TABLE Purchasing (
    Event_Type VARCHAR(255),
    Campaign VARCHAR(255),
    Quantity_Offer VARCHAR(255),
    Quantity_         


        
相关标签:
4条回答
  • 2020-12-22 07:37
    SELECT x.campaign
         , COALESCE(z.event_type,y.event_type,x.event_type) event_type
         , COALESCE(z.quantity_received,y.quantity_order,x.quantity_offer) quantity
      FROM purchasing x
      LEFT 
      JOIN purchasing y 
        ON y.campaign = x.campaign 
       AND y.event_type = 'order'
      LEFT 
      JOIN purchasing z 
        ON z.campaign = y.campaign 
       AND z.event_type = 'received'
    WHERE x.event_type = 'offer'
    

    http://www.sqlfiddle.com/#!9/2b9394/37

    0 讨论(0)
  • 2020-12-22 07:38

    Use this for your query.

    this is based you first make your offer, then comes tghe order and at last comes the received, when 1 of them in that order is empty, then 1 prior must be the current state.

    SELECT
    Campaign,
    IF(QReceived IS NOT NULL, "Received",
       IF(QOrder IS NOT NULL, "Order",
          IF(QOffer IS NOT NULL, "Offer", NULL))) Event_Type,
    IF(QReceived IS NOT NULL, QReceived,
       IF(QOrder IS NOT NULL, QOrder,
          IF(QOffer IS NOT NULL, QOffer, NULL))) qty
          FROM
    (SELECT 
     Campaign,
    SUM(Quantity_Received) QReceived,
    
       SUM(Quantity_Order) QOrder,
       SUM(Quantity_Offer) QOffer
    
    FROm Purchasing
    GROUP BY Campaign) t1
    

    Which gives you foolowing result

    Campaign    Event_Type  qty
    C001        Received    310
    C002        Received    190
    C003        Order       450
    C004        Order       630
    C005        Offer       400
    C006        Offer       300
    

    http://www.sqlfiddle.com/#!9/2b9394/34

    0 讨论(0)
  • 2020-12-22 07:39

    This is a prioritization query.

    In MySQL 8+, use window functions:

    select campaign, event_type,
           coalesce(Quantity_Offer, Quantity_Order, Quantity_Received) as quantity
    from (select p.*,
                 row_number() over (partition by campaign order by field(event_type, 'Received', 'Order', 'Offer')) as seqnum
          from Purchasing p
         ) p
    where seqnum = 1;
    

    In earlier versions, a simple method is a correlated subquery:

    select campaign, event_type,
           coalesce(Quantity_Offer, Quantity_Order, Quantity_Received) as quantity
    from Purchasing p
    where event_type = (select p2.event_type
                        from Purchasing p2
                        where p2.campaign = p.campaign
                        order by field(p2.event_type, 'Received', 'Order', 'Offer')
                        limit 1
                       );
    

    If you have a lot of data, you want an index on Purcahsing(campaign, event_type) for this query.

    Here is a db<>fiddle.

    0 讨论(0)
  • 2020-12-22 07:41

    Since by string comparison 'Offer' < 'Order' < 'Received', you can use the classic way with a group by subquery, to find the "latest" row:

    select 
      p.Campaign,
      p.Event_Type,
      case p.Event_Type
        when 'Order' then p.Quantity_Order
        when 'Offer' then p.Quantity_Offer
        when 'Received' then p.Quantity_Received
      end as Quantity
    from (
      select Campaign, max(Event_Type) as Event_Type
      from Purchasing
      group by Campaign
    ) mx
    natural join Purchasing p
    order by p.Campaign
    

    Result:

    | Campaign | Event_Type | Quantity |
    | -------- | ---------- | -------- |
    | C001     | Received   | 310      |
    | C002     | Received   | 190      |
    | C003     | Order      | 450      |
    | C004     | Order      | 630      |
    | C005     | Offer      | 400      |
    | C006     | Offer      | 300      |
    

    View on DB Fiddle

    But if you were not so lucky with your Event_Type values, or if you want a more solid (more reliable) solution, you would need to define a custom order with either FIELD(), FIND_IN_SET(), a case statement, or a sort mapping (derived) table. Here a way using FIELD():

    select 
      p.Campaign,
      p.Event_Type,
      case p.Event_Type
        when 'Order' then p.Quantity_Order
        when 'Offer' then p.Quantity_Offer
        when 'Received' then p.Quantity_Received
      end as Quantity
    from Purchasing p
    where p.Event_Type = (
      select p1.Event_Type
      from Purchasing p1
      where p1.Campaign = p.Campaign
      order by field(p1.Event_Type, 'Offer', 'Order', 'Received') desc
      limit 1
    )
    order by p.Campaign
    

    View on DB Fiddle

    0 讨论(0)
提交回复
热议问题