How to check if column exists in case statement?
Domanda
I think a case statement would be the best approach to this but am open to any other suggestions. What I am trying to do is this. The query is generated based on a users input regarding the type report that they are seeking. The thing is all possible tables except for one contain a message_id column. On the odd table, I can get the data though another field which is time_sent. Here is an example of a generated query after user input.
SELECT
ps.account_id,
ba.account_name,
NULL AS total_users,
COUNT(DISTINCT(ps.uid)) AS unique_users,
COUNT(DISTINCT r.msg_timestamp) AS messages_received,
NULL AS total_clicks,
NULL AS unique_clicks,
COUNT(DISTINCT s.message_id) AS messages_sent, // THIS IS WHERE I NEED TO USE A CASE OR SOME OTHER MEANS TO DETERMINE IF THE message_id COLUMN EXISTS
COUNT(DISTINCT CASE WHEN ps.added BETWEEN '2020-01-01' AND '2020-06-30' THEN ps.uid END) AS new_users
FROM conversation_facebook_page_subscribers ps
LEFT JOIN conversation_facebook_page_received r ON r.account_id = ps.account_id AND r.uid=ps.uid AND r.received_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN conversation_facebook_page_sent s ON s.account_id = ps.account_id AND s.uid=ps.uid AND s.send_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN business_assets ba ON ba.business_id = '3' AND ba.account_type = 'facebook_page' AND (ba.account_id = ps.account_id OR SUBSTRING_INDEX(ba.account_id, '_', -1) = ps.account_id)
WHERE
(ps.account_id='104522080903905' OR ps.account_id='180004075382887' OR ps.account_id='85825440048')
AND
(r.account_id IS NOT NULL OR s.account_id IS NOT NULL)
GROUP BY ps.account_id, ba.account_name
I have tried to use a case statement to check the name of the table and based on what the table name is select the appropriate field, but that didn't work. I have searched numerous questions on SO to see if I could find something that would work, but nothing I have found works. Can someone please point me in the right direction? Thank you in advance for any assistance.
Soluzione
You can use INFORMATION_SCHEMA COLUMNS Table
But you can't use it in a normal sql statement, because mysql will parse all parts.
I still have problems to understand, why you have missing columns in the first place.
CREATE PROCEDURE `new_procedure` (IN _account_id1,IN _account_id2)
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'conversation_facebook_page_sent '
AND COLUMN_NAME = 'message_id')) THEN
SELECT
ps.account_id,
ba.account_name,
NULL AS total_users,
COUNT(DISTINCT(ps.uid)) AS unique_users,
COUNT(DISTINCT r.msg_timestamp) AS messages_received,
NULL AS total_clicks,
NULL AS unique_clicks,
COUNT(DISTINCT s.message_id) AS messages_sent,
COUNT(DISTINCT CASE WHEN ps.added BETWEEN '2020-01-01' AND '2020-06-30' THEN ps.uid END) AS new_users
FROM conversation_facebook_page_subscribers ps
LEFT JOIN conversation_facebook_page_received r ON r.account_id = ps.account_id AND r.uid=ps.uid AND r.received_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN conversation_facebook_page_sent s ON s.account_id = ps.account_id AND s.uid=ps.uid AND s.send_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN business_assets ba ON ba.business_id = '3' AND ba.account_type = 'facebook_page' AND (ba.account_id = ps.account_id OR SUBSTRING_INDEX(ba.account_id, '_', -1) = ps.account_id)
WHERE
(ps.account_id='104522080903905' OR ps.account_id='180004075382887' OR ps.account_id='85825440048')
AND
(r.account_id IS NOT NULL OR s.account_id IS NOT NULL)
GROUP BY ps.account_id, ba.account_name;
ELSE
SELECT
ps.account_id,
ba.account_name,
NULL AS total_users,
COUNT(DISTINCT(ps.uid)) AS unique_users,
COUNT(DISTINCT r.msg_timestamp) AS messages_received,
NULL AS total_clicks,
NULL AS unique_clicks,
COUNT(DISTINCT s.send_time) AS messages_sent,
COUNT(DISTINCT CASE WHEN ps.added BETWEEN '2020-01-01' AND '2020-06-30' THEN ps.uid END) AS new_users
FROM conversation_facebook_page_subscribers ps
LEFT JOIN conversation_facebook_page_received r ON r.account_id = ps.account_id AND r.uid=ps.uid AND r.received_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN conversation_facebook_page_sent s ON s.account_id = ps.account_id AND s.uid=ps.uid AND s.send_time BETWEEN '1577836800000' AND '1593561599999'
LEFT JOIN business_assets ba ON ba.business_id = '3' AND ba.account_type = 'facebook_page' AND (ba.account_id = ps.account_id OR SUBSTRING_INDEX(ba.account_id, '_', -1) = ps.account_id)
WHERE
(ps.account_id='104522080903905' OR ps.account_id='180004075382887' OR ps.account_id='85825440048')
AND
(r.account_id IS NOT NULL OR s.account_id IS NOT NULL)
GROUP BY ps.account_id, ba.account_name;
END IF;
END