1

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 !=''
 * 
******************************************************************************************** */
1
  • Please provide enough code so others can better understand or reproduce the problem. Commented Nov 29, 2023 at 16:08

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.