functional_deps.sql 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. -- from http://www.depesz.com/index.php/2010/04/19/getting-unique-elements/
  2. CREATE TEMP TABLE articles (
  3. id int CONSTRAINT articles_pkey PRIMARY KEY,
  4. keywords text,
  5. title text UNIQUE NOT NULL,
  6. body text UNIQUE,
  7. created date
  8. );
  9. CREATE TEMP TABLE articles_in_category (
  10. article_id int,
  11. category_id int,
  12. changed date,
  13. PRIMARY KEY (article_id, category_id)
  14. );
  15. -- test functional dependencies based on primary keys/unique constraints
  16. -- base tables
  17. -- group by primary key (OK)
  18. SELECT id, keywords, title, body, created
  19. FROM articles
  20. GROUP BY id;
  21. -- group by unique not null (fail/todo)
  22. SELECT id, keywords, title, body, created
  23. FROM articles
  24. GROUP BY title;
  25. -- group by unique nullable (fail)
  26. SELECT id, keywords, title, body, created
  27. FROM articles
  28. GROUP BY body;
  29. -- group by something else (fail)
  30. SELECT id, keywords, title, body, created
  31. FROM articles
  32. GROUP BY keywords;
  33. -- multiple tables
  34. -- group by primary key (OK)
  35. SELECT a.id, a.keywords, a.title, a.body, a.created
  36. FROM articles AS a, articles_in_category AS aic
  37. WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
  38. GROUP BY a.id;
  39. -- group by something else (fail)
  40. SELECT a.id, a.keywords, a.title, a.body, a.created
  41. FROM articles AS a, articles_in_category AS aic
  42. WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
  43. GROUP BY aic.article_id, aic.category_id;
  44. -- JOIN syntax
  45. -- group by left table's primary key (OK)
  46. SELECT a.id, a.keywords, a.title, a.body, a.created
  47. FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
  48. WHERE aic.category_id in (14,62,70,53,138)
  49. GROUP BY a.id;
  50. -- group by something else (fail)
  51. SELECT a.id, a.keywords, a.title, a.body, a.created
  52. FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
  53. WHERE aic.category_id in (14,62,70,53,138)
  54. GROUP BY aic.article_id, aic.category_id;
  55. -- group by right table's (composite) primary key (OK)
  56. SELECT aic.changed
  57. FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
  58. WHERE aic.category_id in (14,62,70,53,138)
  59. GROUP BY aic.category_id, aic.article_id;
  60. -- group by right table's partial primary key (fail)
  61. SELECT aic.changed
  62. FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
  63. WHERE aic.category_id in (14,62,70,53,138)
  64. GROUP BY aic.article_id;
  65. -- example from documentation
  66. CREATE TEMP TABLE products (product_id int, name text, price numeric);
  67. CREATE TEMP TABLE sales (product_id int, units int);
  68. -- OK
  69. SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
  70. FROM products p LEFT JOIN sales s USING (product_id)
  71. GROUP BY product_id, p.name, p.price;
  72. -- fail
  73. SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
  74. FROM products p LEFT JOIN sales s USING (product_id)
  75. GROUP BY product_id;
  76. ALTER TABLE products ADD PRIMARY KEY (product_id);
  77. -- OK now
  78. SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
  79. FROM products p LEFT JOIN sales s USING (product_id)
  80. GROUP BY product_id;
  81. -- Drupal example, http://drupal.org/node/555530
  82. CREATE TEMP TABLE node (
  83. nid SERIAL,
  84. vid integer NOT NULL default '0',
  85. type varchar(32) NOT NULL default '',
  86. title varchar(128) NOT NULL default '',
  87. uid integer NOT NULL default '0',
  88. status integer NOT NULL default '1',
  89. created integer NOT NULL default '0',
  90. -- snip
  91. PRIMARY KEY (nid, vid)
  92. );
  93. CREATE TEMP TABLE users (
  94. uid integer NOT NULL default '0',
  95. name varchar(60) NOT NULL default '',
  96. pass varchar(32) NOT NULL default '',
  97. -- snip
  98. PRIMARY KEY (uid),
  99. UNIQUE (name)
  100. );
  101. -- OK
  102. SELECT u.uid, u.name FROM node n
  103. INNER JOIN users u ON u.uid = n.uid
  104. WHERE n.type = 'blog' AND n.status = 1
  105. GROUP BY u.uid, u.name;
  106. -- OK
  107. SELECT u.uid, u.name FROM node n
  108. INNER JOIN users u ON u.uid = n.uid
  109. WHERE n.type = 'blog' AND n.status = 1
  110. GROUP BY u.uid;
  111. -- Check views and dependencies
  112. -- fail
  113. CREATE TEMP VIEW fdv1 AS
  114. SELECT id, keywords, title, body, created
  115. FROM articles
  116. GROUP BY body;
  117. -- OK
  118. CREATE TEMP VIEW fdv1 AS
  119. SELECT id, keywords, title, body, created
  120. FROM articles
  121. GROUP BY id;
  122. -- fail
  123. ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
  124. DROP VIEW fdv1;
  125. -- multiple dependencies
  126. CREATE TEMP VIEW fdv2 AS
  127. SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed
  128. FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
  129. WHERE aic.category_id in (14,62,70,53,138)
  130. GROUP BY a.id, aic.category_id, aic.article_id;
  131. ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
  132. ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT; --fail
  133. DROP VIEW fdv2;
  134. -- nested queries
  135. CREATE TEMP VIEW fdv3 AS
  136. SELECT id, keywords, title, body, created
  137. FROM articles
  138. GROUP BY id
  139. UNION
  140. SELECT id, keywords, title, body, created
  141. FROM articles
  142. GROUP BY id;
  143. ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
  144. DROP VIEW fdv3;
  145. CREATE TEMP VIEW fdv4 AS
  146. SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id);
  147. ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
  148. DROP VIEW fdv4;
  149. -- prepared query plans: this results in failure on reuse
  150. PREPARE foo AS
  151. SELECT id, keywords, title, body, created
  152. FROM articles
  153. GROUP BY id;
  154. EXECUTE foo;
  155. ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
  156. EXECUTE foo; -- fail