123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- -- from http://www.depesz.com/index.php/2010/04/19/getting-unique-elements/
- CREATE TEMP TABLE articles (
- id int CONSTRAINT articles_pkey PRIMARY KEY,
- keywords text,
- title text UNIQUE NOT NULL,
- body text UNIQUE,
- created date
- );
- CREATE TEMP TABLE articles_in_category (
- article_id int,
- category_id int,
- changed date,
- PRIMARY KEY (article_id, category_id)
- );
- -- test functional dependencies based on primary keys/unique constraints
- -- base tables
- -- group by primary key (OK)
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id;
- -- group by unique not null (fail/todo)
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY title;
- -- group by unique nullable (fail)
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY body;
- -- group by something else (fail)
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY keywords;
- -- multiple tables
- -- group by primary key (OK)
- SELECT a.id, a.keywords, a.title, a.body, a.created
- FROM articles AS a, articles_in_category AS aic
- WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
- GROUP BY a.id;
- -- group by something else (fail)
- SELECT a.id, a.keywords, a.title, a.body, a.created
- FROM articles AS a, articles_in_category AS aic
- WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
- GROUP BY aic.article_id, aic.category_id;
- -- JOIN syntax
- -- group by left table's primary key (OK)
- SELECT a.id, a.keywords, a.title, a.body, a.created
- FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
- WHERE aic.category_id in (14,62,70,53,138)
- GROUP BY a.id;
- -- group by something else (fail)
- SELECT a.id, a.keywords, a.title, a.body, a.created
- FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
- WHERE aic.category_id in (14,62,70,53,138)
- GROUP BY aic.article_id, aic.category_id;
- -- group by right table's (composite) primary key (OK)
- SELECT aic.changed
- FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
- WHERE aic.category_id in (14,62,70,53,138)
- GROUP BY aic.category_id, aic.article_id;
- -- group by right table's partial primary key (fail)
- SELECT aic.changed
- FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
- WHERE aic.category_id in (14,62,70,53,138)
- GROUP BY aic.article_id;
- -- example from documentation
- CREATE TEMP TABLE products (product_id int, name text, price numeric);
- CREATE TEMP TABLE sales (product_id int, units int);
- -- OK
- SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id, p.name, p.price;
- -- fail
- SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id;
- ALTER TABLE products ADD PRIMARY KEY (product_id);
- -- OK now
- SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id;
- -- Drupal example, http://drupal.org/node/555530
- CREATE TEMP TABLE node (
- nid SERIAL,
- vid integer NOT NULL default '0',
- type varchar(32) NOT NULL default '',
- title varchar(128) NOT NULL default '',
- uid integer NOT NULL default '0',
- status integer NOT NULL default '1',
- created integer NOT NULL default '0',
- -- snip
- PRIMARY KEY (nid, vid)
- );
- CREATE TEMP TABLE users (
- uid integer NOT NULL default '0',
- name varchar(60) NOT NULL default '',
- pass varchar(32) NOT NULL default '',
- -- snip
- PRIMARY KEY (uid),
- UNIQUE (name)
- );
- -- OK
- SELECT u.uid, u.name FROM node n
- INNER JOIN users u ON u.uid = n.uid
- WHERE n.type = 'blog' AND n.status = 1
- GROUP BY u.uid, u.name;
- -- OK
- SELECT u.uid, u.name FROM node n
- INNER JOIN users u ON u.uid = n.uid
- WHERE n.type = 'blog' AND n.status = 1
- GROUP BY u.uid;
- -- Check views and dependencies
- -- fail
- CREATE TEMP VIEW fdv1 AS
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY body;
- -- OK
- CREATE TEMP VIEW fdv1 AS
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id;
- -- fail
- ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
- DROP VIEW fdv1;
- -- multiple dependencies
- CREATE TEMP VIEW fdv2 AS
- SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed
- FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
- WHERE aic.category_id in (14,62,70,53,138)
- GROUP BY a.id, aic.category_id, aic.article_id;
- ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
- ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT; --fail
- DROP VIEW fdv2;
- -- nested queries
- CREATE TEMP VIEW fdv3 AS
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id
- UNION
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id;
- ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
- DROP VIEW fdv3;
- CREATE TEMP VIEW fdv4 AS
- SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id);
- ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
- DROP VIEW fdv4;
- -- prepared query plans: this results in failure on reuse
- PREPARE foo AS
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id;
- EXECUTE foo;
- ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
- EXECUTE foo; -- fail
|