Use correlated subquery over two columns

Michi :

DB Fiddle

CREATE TABLE Purchasing (
    campaign VARCHAR(255),
    main_event VARCHAR(255),
    sub_event VARCHAR(255),
    quantity VARCHAR(255)
);

INSERT INTO Purchasing
(campaign, main_event, sub_event, quantity)
VALUES 
("C001", "Offered", NULL, "500"),
("C001", "Ordered", NULL, "450"),
("C001", "Storing", "Delivered", "465"),
("C001", "Storing", "Recorded", "440"),
("C001", "Storing", "Completed", "445"),

("C002", "Offered", NULL, "600"),
("C002", "Ordered", NULL, "700"),
("C002", "Storing", "Delivered", "690"),
("C002", "Storing", "Recorded", "692"),

("C003", "Offered", NULL, "300"),
("C003", "Ordered", NULL, "250"),
("C003", "Storing", "Delivered", "320"),

("C004", "Offered", NULL, "800"),
("C004", "Ordered", NULL, "870"),
("C004", "Storing", "Delivered", "740"),

("C005", "Offered", NULL, "240"),
("C005", "Ordered", NULL, "250"),
("C005", "Storing", "Delivered", "226"),

("C006", "Offered", NULL, "100"),
("C006", "Ordered", NULL, "105"),

("C007", "Offered", NULl, "900"),
("C008", "Offered", NULl, "400");

The table above displays the purchasing process of different campaigns using main_events and sub_events.
The hierarchy of those events is like this:

main_event = Storing > Ordered > Offered 
sub_event = Completed > Recorded > Delivered

Once a campaign is in the main_event Storing the sub_events apply.


Now, I want to extract the campaigns based on their highest main_event - or in case they already have a sub_event - based on their highest sub_event. The result should look like this:

Campaign       main_event     sub_event         Quantity
C001           Storing        Completed          445
C002           Storing        Recorded           692
C003           Storing        Delivered          320
C004           Storing        Delivered          740
C005           Storing        Delivered          226
C006           Ordered        NULL               105
C007           Offered        NULL               900
C008           Offered        NULL               400

With reference to this question I think I have to combine two correlated subquery:

IF sub_event IS NULL then use

SELECT
campaign, 
main_event,
quantity
FROM Purchasing p
WHERE main_event = (SELECT p2.main_event
                    FROM Purchasing p2
                    WHERE p2.campaign = p.campaign
                    ORDER BY field(p2.main_event, 'Storing', 'Ordered', 'Offered')
                    LIMIT 1
                   );

Else

SELECT
campaign, 
sub_event,
quantity
FROM Purchasing p
WHERE sub_event = (SELECT p3.sub_event
                    FROM Purchasing p3
                    WHERE p3.campaign = p.campaign
                    AND p3.sub_event IS NOT NULL
                    ORDER BY field(p3.sub_event, 'Completed', 'Recorded', 'Delivered')
                    LIMIT 1
                   );

How can I connect those correlated subqueries to get the expected result?

Gordon Linoff :

This would be much simpler if you had a primary key:

CREATE TABLE Purchasing (
    purchasing_id int auto_increment primary key,
    campaign VARCHAR(255),
    main_event VARCHAR(255),
    sub_event VARCHAR(255),
    quantity VARCHAR(255)
);

With that simple addition:

SELECT p.*
FROM Purchasing p
WHERE p.purchasing_id = (SELECT p2.purchasing_id
                         FROM Purchasing p2
                         WHERE p2.campaign = p.campaign
                         ORDER BY field(p2.main_event, 'Storing', 'Ordered', 'Offered'),
                                  field(p2.sub_event, 'Completed', 'Recorded', 'Delivered')
                         LIMIT 1
                        );

Here is a db<>fiddle.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=19357&siteId=1