I'm a new user of PostgreSQL, trying to use DISTINCT ON
but I can't reach my goal.
Here's a brief sketch of my database :
- files with versioning
- fields with model (for form generation purpose)
n:n
relations between files' versions and fields
I would like to retrieve a whole set of fields for a specified file's version.
My problem is that we could have (and we'll) empty values, ie. missing FileVersion_Field relations. I'll try to give you an example bellow :
FileVersion Field
+----------------+---------+---------+ +----------+-------+---------------+
| id_fileversion | id_file | version | | id_field | value | id_fieldmodel |
+----------------+---------+---------+ +----------+-------+---------------+
| 1 | 1 | 1 | | 1 | Smith | 1 |
| 2 | 1 | 2 | | 2 | 20 | 2 |
+----------------+---------+---------+ | 3 | 25 | 2 |
+----------+-------+---------------+
FileVersion_Field FieldModel
+----------------+----------+ +---------------+------+
| id_fileversion | id_field | | id_fieldmodel | type |
+----------------+----------+ +---------------+------+
| 1 | 1 | | 1 | Name |
| 1 | 2 | | 2 | Age |
| 2 | 3 | +---------------+------+
+----------------+----------+
In this example, I would like to get these results:
-- id_file=1 & version=1
Name | Smith
Age | 20
-- id_file=1 & version=2
Name |
Age | 25
Here's what I've tried, which doesn't work :
SELECT DISTINCT ON(FieldModel.id_fieldmodel) *
FROM File
LEFT JOIN FileVersion ON File.id_file = FileVersion.id_file
LEFT JOIN FileVersion_Field ON FileVersion.id_fileversion = FileVersion_Field.id_fileversion
LEFT JOIN Field ON FileVersion_Field.id_field = Field.id_field
RIGHT JOIN FieldModel ON (Field.id_fieldmodel = FieldModel.id_fieldmodel OR FieldModel.id_fieldmodel IS NULL)
WHERE (FieldModel.id_fieldmodel IS NOT NULL AND FileVersion.version = 2 AND File.id_file = 1)
OR (Field.id_fieldmodel IS NULL)
ORDER BY FieldModel.id_fieldmodel;
-- Sample Structure
CREATE TABLE File (
id_file integer PRIMARY KEY);
CREATE TABLE FieldModel (
id_fieldmodel integer PRIMARY KEY, type varchar(50));
CREATE TABLE FileVersion (
id_fileversion integer PRIMARY KEY,
id_file integer, version integer,
CONSTRAINT fk_fileversion_file FOREIGN KEY(id_file) REFERENCES File(id_file));
CREATE TABLE Field (
id_field integer PRIMARY KEY,
id_fieldmodel integer,
value varchar(255),
CONSTRAINT fk_field_fieldmodel FOREIGN KEY(id_fieldmodel) REFERENCES FieldModel(id_fieldmodel));
CREATE TABLE FileVersion_Field (
id_fileversion integer,
id_field integer,
PRIMARY KEY(id_fileversion, id_field),
CONSTRAINT fk_fileversionfield_fileversion FOREIGN KEY(id_fileversion) REFERENCES FileVersion(id_fileversion),
CONSTRAINT fk_fileversionfield_field FOREIGN KEY(id_field) REFERENCES Field(id_field));
-- Sample Data
INSERT INTO File (id_file) VALUES (1);
INSERT INTO FileVersion (id_fileversion, id_file, version) VALUES (1, 1, 1), (2, 1, 2);
INSERT INTO FieldModel (id_fieldmodel, type) VALUES (1, 'Name'), (2, 'Age');
INSERT INTO Field (id_field, id_fieldmodel, value) VALUES (1, 1, 'Smith'), (2, 2, '20'), (3, 2, '25');
INSERT INTO FileVersion_Field (id_fileversion, id_field) VALUES (1, 1), (1, 2), (2, 3);