-1

I've got 4 different user (punter) tables (terrible idea but massive redesign needed a long time ago) that I need to list users from a particular event.

I've looked at this post but no joy MySQL query where JOIN depends on CASE

I've also had a look through similar questions but haven't found anything I can use.

Here's my query:

SELECT 
    sale_id, sale_punter_type, sale_refund, sale_timestamp, 
    sale_punter_type,


    AES_DECRYPT(punter_email, :keyPunter) AS punter_email,
    punter_firstname,
    punter_surname,
    AES_DECRYPT(punter_postcode, :keyPunter) AS punter_postcode,


    AES_DECRYPT(punter_checkout_email, :keyPunter) AS punter_checkout_email,
    punter_checkout_firstname,
    punter_checkout_surname,
    AES_DECRYPT(punter_checkout_postcode, :keyPunter) AS punter_checkout_postcode,


    AES_DECRYPT(punter_compo_email, :keyPunter) AS punter_compo_email,
    punter_compo_firstname,
    punter_compo_surname,


    AES_DECRYPT(punter_shop_email, :keyPunter) AS punter_shop_email,
    punter_shop_firstname,
    punter_shop_surname

FROM 
    sale 
INNER JOIN
    ticket_sold ON sale_id = ticket_sold_sale_no
INNER JOIN
    event ON event_id = ticket_sold_event_no
INNER JOIN 


    (CASE
        WHEN 
            sale_punter_type = 1 THEN punter ON punter_id = sale_punter_no 
        WHEN 
            sale_punter_type = 2 THEN punter_checkout ON punter_checkout_id = sale_punter_no 
        WHEN 
            sale_punter_type = 3 THEN punter_compo ON punter_compo_id = sale_punter_no 
        WHEN 
            sale_punter_type = 4 THEN punter_shop ON punter_shop_id = sale_punter_no 
    END) 


WHERE 
    event_id = :id

I tried using LEFT JOIN:

SELECT 
    sale_id, sale_punter_type, sale_refund, sale_timestamp, 
    sale_punter_type,


    AES_DECRYPT(punter_email, :keyPunter) AS punter_email,
    punter_firstname,
    punter_surname,
    AES_DECRYPT(punter_postcode, :keyPunter) AS punter_postcode,


    AES_DECRYPT(punter_checkout_email, :keyPunter) AS punter_checkout_email,
    punter_checkout_firstname,
    punter_checkout_surname,
    AES_DECRYPT(punter_checkout_postcode, :keyPunter) AS punter_checkout_postcode,


    AES_DECRYPT(punter_compo_email, :keyPunter) AS punter_compo_email,
    punter_compo_firstname,
    punter_compo_surname,


    AES_DECRYPT(punter_shop_email, :keyPunter) AS punter_shop_email,
    punter_shop_firstname,
    punter_shop_surname

FROM 
    sale 
INNER JOIN
    ticket_sold ON sale_id = ticket_sold_sale_no
INNER JOIN
    event ON event_id = ticket_sold_event_no
INNER JOIN 
    punter ON punter_id = sale_punter_no 
LEFT JOIN 
    punter_checkout ON punter_checkout_id = sale_punter_no 
LEFT JOIN 
    punter_compo ON punter_compo_id = sale_punter_no 
LEFT JOIN 
    punter_shop ON punter_shop_id = sale_punter_no 
WHERE 
    event_id = :id

but it returned users with the same ID but from different tables.

I'm not sure how to explain it, I need something like

IF sale_punter_no = 1 THEN INNER JOIN punter ON punter_id = sale_punter_no

Hopefully that makes sense and mysql can do such things

Thank you

2 Answers2

0

You can perform LEFT JOIN on each table as shown below.

However, from your example it's not clear which columns do you want to use from each related table; you'll need to use COALESCE() or similar to merge them accordingly. it's always a good pactice to prepend each column with the table (or table alias) it belongs to.

Here's the query:

SELECT 
    sale_id, sale_punter_type, sale_refund, sale_timestamp, 
    sale_punter_type,

    AES_DECRYPT(punter_email, :keyPunter) AS punter_email,
    punter_firstname,
    punter_surname,
    AES_DECRYPT(punter_postcode, :keyPunter) AS punter_postcode,

    AES_DECRYPT(punter_checkout_email, :keyPunter) AS punter_checkout_email,
    punter_checkout_firstname,
    punter_checkout_surname,
    AES_DECRYPT(punter_checkout_postcode, :keyPunter) AS punter_checkout_postcode,

    AES_DECRYPT(punter_compo_email, :keyPunter) AS punter_compo_email,
    punter_compo_firstname,
    punter_compo_surname,

    AES_DECRYPT(punter_shop_email, :keyPunter) AS punter_shop_email,
    punter_shop_firstname,
    punter_shop_surname

FROM sale 
JOIN ticket_sold ON sale_id = ticket_sold_sale_no
JOIN event ON event_id = ticket_sold_event_no

LEFT JOIN punter ON punter_id = sale_punter_no AND sale_punter_type = 1
LEFT JOIN punter_checkout ON punter_checkout_id = sale_punter_no AND sale_punter_type = 2
LEFT JOIN punter_compo ON punter_compo_id = sale_punter_no AND sale_punter_type = 3
LEFT JOIN punter_shop ON punter_shop_id = sale_punter_no AND sale_punter_type = 4
WHERE event_id = :id
The Impaler
  • 45,731
  • 9
  • 39
  • 76
0

Your IF/CASE statements need to be in the SELECT. So, start with your LEFT JOIN query. Try this for your select:

SELECT 
    sale_id, sale_punter_type, sale_refund, sale_timestamp, 
    sale_punter_type,

    CASE sale_punter_type
      WHEN 1 THEN AES_DECRYPT(punter_email, :keyPunter)
      WHEN 2 THEN AES_DECRYPT(punter_checkout_email, :keyPunter)
      WHEN 3 THEN AES_DECRYPT(punter_compo_email, :keyPunter)
      WHEN 4 THEN AES_DECRYPT(punter_shop_email, :keyPunter)
    END punter_email,
    CASE sale_punter_type
      WHEN 1 THEN punter_firstname
      WHEN 2 THEN punter_checkout_firstname
      WHEN 3 THEN punter_compo_firstname
      WHEN 4 THEN punter_shop_firstname
    END punter_firstname,
    CASE sale_punter_type
      WHEN 1 THEN punter_surname
      WHEN 2 THEN punter_checkout_surname
      WHEN 3 THEN punter_compo_surname
      WHEN 4 THEN punter_shop_surname
    END punter_surname,
    CASE sale_punter_type
      WHEN 1 THEN AES_DECRYPT(punter_postcode, :keyPunter)
      WHEN 2 THEN AES_DECRYPT(punter_checkout_postcode, :keyPunter)
      ELSE NULL
    END punter_postcode
thelr
  • 1,134
  • 11
  • 30