【发布时间】:2014-05-12 22:31:37
【问题描述】:
我的数据库结构如下:
CREATE TABLE categories (
name VARCHAR(30) PRIMARY KEY
);
CREATE TABLE additives (
name VARCHAR(30) PRIMARY KEY
);
CREATE TABLE beverages (
name VARCHAR(30) PRIMARY KEY,
description VARCHAR(200),
price NUMERIC(5, 2) NOT NULL CHECK (price >= 0),
category VARCHAR(30) NOT NULL REFERENCES categories(name) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE b_additives_xref (
bname VARCHAR(30) REFERENCES beverages(name) ON DELETE CASCADE ON UPDATE CASCADE,
aname VARCHAR(30) REFERENCES additives(name) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(bname, aname)
);
INSERT INTO categories VALUES
('Cocktails'), ('Biere'), ('Alkoholfreies');
INSERT INTO additives VALUES
('Kaliumphosphat (E 340)'), ('Pektin (E 440)'), ('Citronensäure (E 330)');
INSERT INTO beverages VALUES
('Mojito Speciale', 'Cocktail mit Rum, Rohrzucker und Minze', 8, 'Cocktails'),
('Franziskaner Weißbier', 'Köstlich mildes Hefeweizen', 6, 'Biere'),
('Augustiner Hell', 'Frisch gekühlt vom Fass', 5, 'Biere'),
('Coca Cola', 'Coffeeinhaltiges Erfrischungsgetränk', 2.75, 'Alkoholfreies'),
('Sprite', 'Erfrischende Zitronenlimonade', 2.50, 'Alkoholfreies'),
('Karaffe Wasser', 'Kaltes, gashaltiges Wasser', 6.50, 'Alkoholfreies');
INSERT INTO b_additives_xref VALUES
('Coca Cola', 'Kaliumphosphat (E 340)'),
('Coca Cola', 'Pektin (E 440)'),
('Coca Cola', 'Citronensäure (E 330)');
我想要实现的是列出所有饮料及其属性(price、description 等)并从b_additives_xref 表中添加另一列additives,该列包含一个包含所有添加剂的串联字符串包含在每种饮料中。
我的查询目前看起来像这样并且几乎可以正常工作(我猜):
SELECT
beverages.name AS name,
beverages.description AS description,
beverages.price AS price,
beverages.category AS category,
string_agg(additives.name, ', ') AS additives
FROM beverages, additives
LEFT JOIN b_additives_xref ON b_additives_xref.aname = additives.name
GROUP BY beverages.name
ORDER BY beverages.category;
输出如下:
Coca Cola | Coffeeinhaltiges Erfrischungsgetränk | 2.75 | Alkoholfreies | Kaliumphosphat (E 340), Pektin (E 440), Citronensäure (E 330)
Karaffe Wasser | Kaltes, gashaltiges Wasser | 6.50 | Alkoholfreies | Kaliumphosphat (E 340), Pektin (E 440), Citronensäure (E 330)
Sprite | Erfrischende Zitronenlimonade | 2.50 | Alkoholfreies | Kaliumphosphat (E 340), Pektin (E 440), Citronensäure (E 330)
Augustiner Hell | Frisch gekühlt vom Fass | 5.00 | Biere | Kaliumphosphat (E 340)[...]
这当然是错误的,因为 b_additives_xref 表中只有“可口可乐”有现有行。
除了“Coca Cola”行之外,所有其他行在“additives”列中都应该有“null”或“empty field”值。我做错了什么?
【问题讨论】:
-
提示#1:使用数字 ID 而不是 varchar 列,因为它们用作 FK。
-
+1 表示很好的问题
-
我首先为主键设置了数字 ID,但有人告诉我 VARCHAR 和 NUMERIC FK 之间的速度并没有真正的区别。这个说法是假的吗?如果不是,那么使用数字标识符列的优势在哪里?
-
0) 键分离值 1) 空间 2) 固定大小。 3)时间。 ad 12:考虑(多个)FK 指向相同的附加记录 ad0:考虑在(多个)FK 指向一个条目的情况下重命名或修复错字。
-
好的,我将它切换回 NUMERICs :-) 感谢您提供信息。
标签: sql postgresql join database-design left-join