-- Dear SQLiters,

-- Here is schema first, table is below, 
-- followed by offending statement.
-- you can copy and paste the entire body
-- my comments are SQL compatible

-----------------------------------------
-- STEP 1 --
-- create gender and handedness tables to fix possible values
-- then create subject table
-----------------------------------------
CREATE TABLE gender(
  gender      TEXT PRIMARY KEY NOT NULL,
  description TEXT
);

INSERT OR IGNORE INTO gender (gender, description) VALUES ('Male', 'male 
gender');
INSERT OR IGNORE INTO gender (gender, description) VALUES ('Female', 'female 
gender');

CREATE TABLE handedness(
  handedness  TEXT PRIMARY KEY NOT NULL,
  description TEXT
);

-- force dob yyyy-mm-dd or NULL
CREATE TABLE subject(
  subjectID  INT PRIMARY KEY NOT NULL,
  dob        TEXT CHECK (dob IS date(dob)),
  gender     TEXT REFERENCES gender(gender) ON UPDATE CASCADE,
  race       TEXT,
  handedness TEXT REFERENCES handedness(handedness) ON UPDATE CASCADE
);


-- STEP 2 --
CREATE TABLE MRIMetric(
  metricName  TEXT PRIMARY KEY NOT NULL,
  description TEXT,
  units       TEXT
);


-- STEP 3 --
-- examType.examType = name of the table where
-- to find exam specifics
CREATE TABLE ExamType(
  examType    TEXT PRIMARY KEY NOT NULL,
  description TEXT
);

INSERT OR IGNORE INTO ExamType (examType, description) VALUES ('MRIExam', 'any 
MRI exam');
INSERT OR IGNORE INTO ExamType (examType, description) VALUES 
('demographicExam', 'view on subject table');
INSERT OR IGNORE INTO ExamType (examType)              VALUES ('educationExam');

-- assume date yyyy-mm-dd 
CREATE TABLE Exam(
  examID      TEXT PRIMARY KEY NOT NULL,
  subjectID   INTEGER NOT NULL REFERENCES subject(subjectID) ON UPDATE CASCADE 
ON DELETE CASCADE,
  examType    TEXT NOT NULL REFERENCES examType(examType) ON UPDATE CASCADE,
  comments    TEXT,
  date        TEXT CHECK (date IS date(date)),
  age         INTEGER
);

-----------------------------------------
-- create triggers to compute age on various updates and inserts
-----------------------------------------
-- automatically compute age at the time of exam when exam is inserted
CREATE TRIGGER ageCalculatorOnExamInsert AFTER INSERT ON Exam FOR EACH ROW BEGIN
  UPDATE OR IGNORE Exam SET age = (
    SELECT coalesce(
             strftime('%Y', NEW.date) - strftime('%Y', subject.dob) -1
          + (strftime('%m-%d', NEW.date) >= strftime('%m-%d', subject.dob)),
            NEW.age)
    FROM subject
    WHERE subject.subjectID = NEW.subjectID
    ) -- this ends select statement that joins exam and subject tables
  WHERE Exam.examID = NEW.examID;
END;

-- automatically compute age at the time of exam when exam is updated
CREATE TRIGGER ageCalculatorOnExamUpdate AFTER UPDATE ON Exam FOR EACH ROW BEGIN
  UPDATE OR IGNORE Exam SET age = (
    SELECT coalesce(
             strftime('%Y', NEW.date) - strftime('%Y', subject.dob) -1
          + (strftime('%m-%d', NEW.date) >= strftime('%m-%d', subject.dob)),
            NEW.age)
    FROM subject
    WHERE subject.subjectID = NEW.subjectID
    ) -- this ends select statement that joins exam and subject tables
  WHERE Exam.examID = NEW.examID;
END;

-- automatically compute age at the time of exam when subject.DOB is updated
CREATE TRIGGER ageCalculatorOnSubjectUpdate AFTER UPDATE ON subject FOR EACH 
ROW BEGIN
  UPDATE OR IGNORE Exam SET age = (
    SELECT coalesce(
             strftime('%Y', e.date) - strftime('%Y', NEW.dob) -1
          + (strftime('%m-%d', e.date) >= strftime('%m-%d', NEW.dob)),
            e.age)
    FROM Exam e
    WHERE Exam.examID = e.examID
    ) -- this ends select statement that joins exam and subject tables
  WHERE Exam.subjectID = NEW.subjectID;
END;

-- STEP 4 --
CREATE TABLE MRIExam(
  examID       TEXT NOT NULL REFERENCES Exam(examID) ON UPDATE CASCADE ON 
DELETE CASCADE,
  ResearchName TEXT,
  MRN          INTEGER,
  pipeline     TEXT,
  DICOMFolder  TEXT,
  PRIMARY KEY (examID)
);

CREATE TABLE MRIExamAccession(
  examID      TEXT NOT NULL REFERENCES MRIExam(examID) ON UPDATE CASCADE ON 
DELETE CASCADE,
  accession   INTEGER,
  UNIQUE (examID, accession)
);

CREATE INDEX MRIExamAccessionIndex ON MRIExamAccession(examID);

-- STEP 5 --
CREATE TABLE badMRIMetric(
  examID      TEXT NOT NULL REFERENCES MRIExam(examID) ON UPDATE CASCADE ON 
DELETE CASCADE,
  metricName  TEXT NOT NULL REFERENCES MRIMetric(metricName) ON UPDATE CASCADE,
  reason      TEXT, 
  PRIMARY KEY (examID, metricName)
);

-----------------------------------------
-- STEP 6 --
-- create wave table
-----------------------------------------
CREATE TABLE aboutWave(
  waveID      TEXT PRIMARY KEY NOT NULL,
  description TEXT
);

INSERT OR IGNORE INTO aboutWave (waveID, description) VALUES ('time1', 'first 
scan');

-- force uniqueness of subject+examType+wave.
-- can not have several instances of one exam type within a wave
-- given examID can be assigned to several waves
CREATE TABLE wave(
  subjectID   INT  NOT NULL REFERENCES subject(subjectID) ON UPDATE CASCADE ON 
DELETE CASCADE,
  examType    TEXT NOT NULL REFERENCES ExamType(examType) ON UPDATE CASCADE,
  waveID      TEXT NOT NULL REFERENCES aboutWave(waveID)  ON UPDATE CASCADE,
  examID      TEXT NOT NULL REFERENCES Exam(examID)       ON UPDATE CASCADE ON 
DELETE CASCADE,
  PRIMARY KEY (subjectID, examType, waveID)
);

CREATE INDEX waveIndex ON wave(examID);


-----------------------------------------
-- STEP 7 --
-- create view on subject table as demographicExam
-- use subjectID as examID
-----------------------------------------
CREATE VIEW IF NOT EXISTS demographicExam AS 
  SELECT subjectID AS examID,
         dob,
         gender,
         race,
         handedness
  FROM subject;

-- automatically add demographic exam to wave and Exam tables when subject is 
inserted
-- use subjectID as examID
CREATE TRIGGER demographicInsert AFTER INSERT ON subject FOR EACH ROW BEGIN
  INSERT INTO Exam (subjectID, examID, examType) VALUES (NEW.subjectID, 
NEW.subjectID, 'demographicExam');
  INSERT INTO wave (subjectID, examType, waveID, examID) VALUES (NEW.subjectID, 
'demographicExam', 'time1', NEW.subjectID);
END;


-- STEP 8 --
CREATE TABLE educationExam(
  examID      TEXT NOT NULL REFERENCES Exam(examID) ON UPDATE CASCADE ON DELETE 
CASCADE,
  education   INTEGER,
  PRIMARY KEY (examID)
);


-----------------------------------------
---------- end of schema
-----------------------------------------

CREATE TABLE demographics(
  "subjectID" TEXT,
  "DOB" TEXT,
  "Age" TEXT,
  "Education" TEXT,
  "Gender" TEXT
);
INSERT INTO "demographics" VALUES('0001','1992-05-04','23','16','Female');
INSERT INTO "demographics" VALUES('0002','1992-07-02','22','17','Female');
INSERT INTO "demographics" VALUES('0003','1986-01-02','29','13','Female');
INSERT INTO "demographics" VALUES('0004','1989-04-05','26','12','Female');
INSERT INTO "demographics" VALUES('0005','1989-10-15','25','18','Male');
INSERT INTO "demographics" VALUES('0006','1989-08-14','25','19','Female');
INSERT INTO "demographics" VALUES('0007','1990-04-02','25','14','Female');
INSERT INTO "demographics" VALUES('0008','1982-03-17','33','13','Male');
INSERT INTO "demographics" VALUES('0009','1966-03-03','49','16','Male');
INSERT INTO "demographics" VALUES('0010','1988-09-14','26','13','Female');
INSERT INTO "demographics" VALUES('0011','1987-11-22','27','14','Female');
INSERT INTO "demographics" VALUES('0012','1969-02-12','46','20','Male');
INSERT INTO "demographics" VALUES('0013','1988-05-03','27','19','Male');
INSERT INTO "demographics" VALUES('0014','1966-08-24','48','16','Female');
INSERT INTO "demographics" VALUES('0015','1970-04-20','45','17','Female');
INSERT INTO "demographics" VALUES('0016','1991-08-03','23','17','Male');
INSERT INTO "demographics" VALUES('0017','1989-12-15','25','18','Male');
INSERT INTO "demographics" VALUES('0018','1991-12-18','23','16','Male');
INSERT INTO "demographics" VALUES('0019','1989-04-24','26','20','Male');
INSERT INTO "demographics" VALUES('0020','1965-10-15','49','20','Male');
INSERT INTO "demographics" VALUES('0021','1980-01-03','35','15','Female');
INSERT INTO "demographics" VALUES('0022','1979-01-05','36','11','Male');
INSERT INTO "demographics" VALUES('0023','1990-10-28','24','16','Male');
INSERT INTO "demographics" VALUES('0024','1983-10-13','31','14','Male');
INSERT INTO "demographics" VALUES('0025','1991-07-10','23','14','Male');
INSERT INTO "demographics" VALUES('0026','1991-04-28','24','18','Male');
INSERT INTO "demographics" VALUES('0027','1988-07-05','26','18.5','Male');
INSERT INTO "demographics" VALUES('0028','1987-04-22','28','21','Male');
INSERT INTO "demographics" VALUES('0029','1988-08-04','26','18','Male');
INSERT INTO "demographics" VALUES('0030','1967-12-13','47','16','Male');
INSERT INTO "demographics" VALUES('0031','1983-11-05','31','16','Male');

-- Offending statement:

PRAGMA foreign_keys=ON;
INSERT OR IGNORE INTO subject(subjectID, dob, gender)
           SELECT subjectID, dob, gender FROM demographics;
PRAGMA integrity_check;

-- Roman

Reply via email to