PostgreSQL 插入 table 并从多个其他 table 中选择子查询

PostgreSQL Insert into table with subquery selecting from multiple other tables

我正在学习 SQL (postgres) 并尝试将一条记录插入到 table 中,该记录引用了另外两个 table 的记录,作为外键。

以下是我用于创建 table 和记录的语法:

-- Create a person table + insert single row
CREATE TABLE person (
    pname VARCHAR(255) NOT NULL,
    PRIMARY KEY (pname)
);
INSERT INTO person VALUES ('personOne');

-- Create a city table + insert single row
CREATE TABLE city (
    cname VARCHAR(255) NOT NULL,
    PRIMARY KEY (cname)
);
INSERT INTO city VALUES ('cityOne');

-- Create a employee table w/ForeignKey reference
CREATE TABLE employee (
    ename VARCHAR(255) REFERENCES person(pname) NOT NULL,
    ecity VARCHAR(255) REFERENCES city(cname) NOT NULL,
    PRIMARY KEY(ename, ecity)
);

-- create employee entry referencing existing records
INSERT INTO employee VALUES(
    SELECT pname FROM person
        WHERE pname='personOne' AND  <-- ISSUE
    SELECT cname FROM city
        WHERE cname='cityOne
);

请注意最后一段代码,我正在对员工 table 执行 INSERT,我不知道如何将多个 SELECT 子串在一起查询以从人员和城市 table 获取现有记录,这样我就可以创建一个具有如下属性的新员工条目:

ename='personOne' ecity='cityOne'

我的 class 教科书没有像这样深入研究子查询,我找不到任何与我的示例足够相似的示例,因此我可以理解如何针对此用例调整它们.

不胜感激。

城市和人之间似乎没有任何明显的关系会让你的生活变得艰难

将具有两个提供信息的碱基 table 的 select 转换为插入片段的一般模式是:

INSERT INTO table(column,list,here)
SELECT column,list,here 
FROM
  a 
  JOIN b ON a.x = b.y

在您的情况下, 上实际上没有什么可加入的,因为您的单列 table 没有共同的列。提供例如 cityname in Person(因为看起来更有可能一个城市有很多人)然后你可以做

INSERT INTO employee(personname,cityname)
SELECT p.pname, c.cname  
FROM
  person p
  JOIN city c ON p.cityname = c.cname 

但即便如此,table 之间还是相互关联的,不需要第三个 table 所以这可能只是一种学术练习,而不是你在现实世界

如果你只想将每个人与每个城市混合在一起,你可以这样做:

INSERT INTO employee(personname,cityname)
SELECT pname, cname 
FROM
  person p
  CROSS JOIN city c 

但请注意,两个人和两个城市将导致插入 4 行,依此类推(20 人和 40 个城市,800 行。相当无用恕我直言)

不过,我相信首先显示的一般模式足以满足您的学习需要;写一个 SELECT 显示你要插入的数据,然后简单地在上面写 INSERT INTO table(columns) 。插入的列数必须与 selected 的列数匹配。不要忘记,如果查询中没有列具有信息 (INSERT INTO X(p,c,age) SELECT personname, cityname, 23 FROM ...)

,您可以 select 固定值

以下内容适合您:

INSERT INTO employee
SELECT pname, cname FROM person, city
WHERE pname='personOne' AND cname='cityOne';

这是一个 cross join 生成两个表的笛卡尔积(因为 link 这两个表没有任何关系)。它读起来有点奇怪,因为您可以直接插入值。但我认为这是因为这是一个学习练习。

请注意,您的创建员工中有错字。主键前缺少逗号。