Gabrielle
Gabrielle

Reputation: 11

How can I create a loop which uses the values from another table as a dynamic variable in the looping query?

Context: I have a table of disease and symptoms which was downloaded online. Each row represents a disease and has a variable number of populated columns which contain a string with both the symptom and the symptom frequency.

Target: I want to create a table which has a single column and lists all the symptoms.

How: To do this, I want to insert into the table the results from a query which takes the column name as a dynamic parameter, and loop over all the columns.

Problem: The problem is, the way I've written the loop, it sees the column name as a string instead of "evaluating" it as a column name.

What happens: Below is the code we have tried. The last part (5) is where the problem lies. The loop essentially does the following for each column name

SELECT left('C3', strpos('C3', ':') - 1) as symptom_desc
FROM base_table b
WHERE 'C3' !=''

instead of doing

SELECT left(C3, strpos(C3, ':') - 1) as symptom_desc
FROM base_table b
WHERE C3 !=''
/*************************************************************************************************************
 * 1. Here we create a base table which is a subset of the raw data we have downloaded online 
 * and have imported in the database in its original format
 * 
 * Each row represents a disease and has its associated symptoms and frequency across the columns to the right
 * 
 * We will want to run a query on each column of this table through a loop to create a single column table with
 * all the symptoms
 * 
**************************************************************************************************************8*/

DROP TABLE base_table;
CREATE TABLE base_table
(
C1  Varchar ,
C2  Varchar ,
C3  Varchar ,
C4  Varchar ,
C5  Varchar ,
C6  Varchar     );


INSERT INTO base_table
VALUES

('Abdominal aortic aneurysm',   'Disease',  'anyloc:0.5',   'shock - hypovolemic:0.5'   ,'flank pain:0.5',  'peripheral artery disease:0.5'),
('Abdominal aortic aneurysm ruptured',  'Disease',  'diabetes mellitus - type 2:0.5',   'anyloc:0.5',   'shock - hypovolemic:0.5',  'flank pain:0.5'),
('Abdominal pregnancy', 'Disease',  'increasing abdominal girth:0.5',   'anyloc:0.5',   'adult:0.5',    'amenorrhea:0.5'),
('Abo incompatibility reaction',    'Disease',  'fever:0.75',   'tachycardia:0.75', 'chills:0.5',   'rigors:0.5'),
('Abrasion of teeth',   'Disease',  'tongue jewellery:0.3', 'bruxism:0.6',  'high-fiber diet:0.1',  'loss of tooth structure:1'),
('Abscess of anal and rectal regions',  'Disease',  'severe anal pain:0.8', 'fever:0.75',   'malaise:0.75', 'draining fistula:0.5')
;


/***************************************************************************************
 * 2. Here we inspect the format of the base table
 ***************************************************************************************/

SELECT *
FROM base_table;

/***************************************************************************************
 * 3. Here we create a table shell to store only the symptom names
 ***************************************************************************************/


CREATE TABLE all_symptoms (symptom_desc varchar);

/***************************************************************************************
 * 4. Here we demonstrate the query we wish to run on each column
 ***************************************************************************************/

--INSERT INTO all_symptoms 
SELECT left(C3, strpos(C3, ':') - 1) as symptom_desc
FROM base_table b
WHERE C3 != ''


/***************************************************************************************
 * 5. Here we try to use a FOR LOOP to run the above query for multiple columns
 ***************************************************************************************/


do
$$
declare
    cn record;
begin
    --The below creates a record for all the column names of the base table, except for the two first columns
    for cn in SELECT column_name FROM information_schema.Columns WHERE table_schema = 'public' AND table_name = 'base_table' and column_name not in ('c1','c2')
   --Here we attempt to loop through each of those columns, passing the column name as an argument
    loop 
    INSERT all_symptoms 
    SELECT left(cn.column_name, strpos(cn.column_name, ':') - 1) as symptom_desc
    FROM base_table b 
    WHERE cn.column_name != ''
;
    end loop;
end;
$$


/*******************************************************************************************
 * 
 * The problem is that is doesn't "evaluate" the column name but sees it as a string, 
 * i.e. it does 
 * SELECT left('C3', strpos('C3', ':') - 1) as symptom_desc
 * FROM base_table b
 * WHERE 'C3' !=''
 * 
 * instead of doing 
 * 
 * SELECT left(C3, strpos(C3, ':') - 1) as symptom_desc
 * FROM base_table b
 * WHERE C3 !=''
 * 
******************************************************************************************** */

Upvotes: 1

Views: 19

Answers (0)

Related Questions