[删除了初始响应,因为它不起作用。为了使其发挥作用,我在第二次编辑中提出了更可取的查询。]
编辑
您似乎正在尝试创建一个模式来跟踪在不同位置工作的人员,并且从您的数据来看,他们似乎可能在不同的办公室中拥有多个头衔。下面的模式将允许您只定义每个人、工作和位置一次,然后使用链接表将它们连接起来。
TABLE People
p_id INT AI PK
p_name VARCHAR
p_sex BOOL
...
TABLE Offices
o_ID INT AI PK
o_name VARCHAR
o_location VARCHAR
...
TABLE Jobs
j_ID INT AI PK
j_name VARCHAR
...
TABLE People_Jobs_Offices --linking table
p_ID INT PK
o_ID INT PK
j_ID INT PK
现在获取马德里或哥本哈根的所有系统管理员:
SELECT *
FROM People_Jobs_Offices pjo
INNER JOIN People p
ON pjo.p_id = p.p_id
INNER JOIN Jobs j
on pjo.j_id = j.j_id
INNER JOIN Offices o
ON pjo.o_id = o.o_id
WHERE
j.j_name = 'SYSADMIN'
AND ( o.o_location = 'MADRID'
OR o.o_location = 'COPENHAGEN' )
这种方法称为数据库规范化,通常可以充分利用任何 RDBMS 中的索引,并通过避免数据重复将表中的行数保持在最低限度。
编辑²
我重新摆弄了你的 SQLfiddle。其中大部分必须以编程方式完成,即。确定哪些类别/多少连接/表别名/列名,但您想从ID
列引用的任何表开始,以便为这些连接提供一个可靠的起点,我刚刚创建了该users
表以进行说明。
CREATE TABLE users (`ID` varchar(16),`name` varchar(16));
INSERT INTO users (`ID`, `name`)
VALUES ('A', 'andrew'), ('B', 'bob'), ('C', 'charla');
和查询:
SELECT u.*,
gen.value 'gender',
pos.value 'position',
loc.value 'location'
FROM users u
LEFT JOIN yourtable gen
ON u.ID = gen.ID
AND gen.category = 'GENDER'
LEFT JOIN yourtable pos
ON u.id = pos.id
AND pos.category = 'POSITION'
LEFT JOIN yourtable loc
ON u.id = loc.id
AND loc.category = 'LOCATION'
和输出:
ID NAME GENDER POSITION LOCATION
A andrew MALE (null) COPENHAGEN
A andrew MALE (null) MADRID
B bob MALE WEBDESIGN MADRID
B bob MALE SYSADMIN MADRID
C charla FEMALE (null) MADRID
C charla FEMALE (null) AARHUS
我还要确保,由于有可能进行许多连接,您在表中的 3 列(如果不是全部)category
上都有索引。ID