سؤال

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.

هل كانت مفيدة؟

المحلول

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى dba.stackexchange
scroll top