-- http://stackoverflow.com/questions/15880634/view-on-a-table-referenced-by-two-foreign-keys-from-the-same-table

CREATE TABLE image (
	id serial PRIMARY KEY,
	name text
);
INSERT INTO image(name) VALUES ('image 1');
INSERT INTO image(name) VALUES ('image 2');
INSERT INTO image(name) VALUES ('image 3');

CREATE TABLE item (
	id serial PRIMARY KEY,
	name text,
	im_left int,
	FOREIGN KEY (im_left) REFERENCES image(id),
	im_right int,
	FOREIGN KEY (im_right) REFERENCES image(id)
);
INSERT INTO item(name,im_left,im_right) VALUES ('item 1',1,2);
INSERT INTO item(name,im_left,im_right) VALUES ('item 2',1,3);
INSERT INTO item(name,im_left,im_right) VALUES ('item 3',2,3);

CREATE VIEW imagev_v1 AS (
	SELECT image.id, image.name,
		array_agg(li.id) AS left_ids,
		array_agg(li.name) AS left_names,
		array_agg(ri.id) AS right_ids,
		array_agg(ri.name) AS right_names
	FROM image
		LEFT OUTER JOIN item AS li ON li.im_left=image.id
		LEFT OUTER JOIN item AS ri ON ri.im_right=image.id
	GROUP BY image.id, image.name
	ORDER BY name ASC
);

testdb=> select * from imagev_v1 ;
 id |  name   |  left_ids   |     left_names      |  right_ids  |     right_names
----+---------+-------------+---------------------+-------------+---------------------
  1 | image 1 | {1,2}       | {"item 1","item 2"} | {NULL,NULL} | {NULL,NULL}
  2 | image 2 | {3}         | {"item 3"}          | {1}         | {"item 1"}
  3 | image 3 | {NULL,NULL} | {NULL,NULL}         | {2,3}       | {"item 2","item 3"}
(3 rows)

INSERT INTO item(name,im_left,im_right) VALUES ('item 4',3,3);

testdb=> select * from imagev_v1 ;
 id |  name   | left_ids |          left_names          |  right_ids  |         right_names
----+---------+----------+------------------------------+-------------+------------------------------
  1 | image 1 | {1,2}    | {"item 1","item 2"}          | {NULL,NULL} | {NULL,NULL}
  2 | image 2 | {3}      | {"item 3"}                   | {1}         | {"item 1"}
  3 | image 3 | {4,4,4}  | {"item 4","item 4","item 4"} | {2,3,4}     | {"item 2","item 3","item 4"}
(3 rows)

CREATE VIEW imagev_v2 AS (
	SELECT image.id, image.name,
		array_agg(item.id) AS item_ids,
		array_agg(item.name) AS item_names
	FROM image
		LEFT OUTER JOIN item ON item.im_left=image.id OR item.im_right=image.id
	GROUP BY image.id, image.name
	ORDER BY name ASC
);

testdb=> select * from imagev_v2 ;
 id |  name   | item_ids |          item_names
----+---------+----------+------------------------------
  1 | image 1 | {1,2}    | {"item 1","item 2"}
  2 | image 2 | {1,3}    | {"item 1","item 3"}
  3 | image 3 | {2,3,4}  | {"item 2","item 3","item 4"}
(3 rows)

DROP VIEW IF EXISTS imagev_v3;
CREATE VIEW imagev_v3 AS (
	SELECT i.id, i.name, 
		array_agg(CASE 
					WHEN t.im_left<>i.id AND t.im_right<>i.id THEN 'None'
					WHEN t.im_left=i.id  AND t.im_right<>i.id THEN 'Left'
					WHEN t.im_left<>i.id AND t.im_right=i.id  THEN 'Right' 
					ELSE 'Both' 
				END) AS item_sources,
		array_agg(t.id) AS item_ids,
		array_agg(t.name) AS item_names
	FROM image AS i 
		LEFT OUTER JOIN item AS t
			ON t.im_left = i.id OR t.im_right = i.id
	GROUP BY i.id, i.name
);
