我有一个像这样的MySql表:
ID Category Value
A LOCATION COPENHAGEN
A LOCATION MADRID
B LOCATION MADRID
C LOCATION MADRID
C LOCATION AARHUS
C POSITION WEBDESIGN
D POSITION SYSADMIN
D POSITION WEBDESIGN
A GENDER MALE
B GENDER MALE
C GENDER FEMALE
Id,Category和Values共同构成了关键。请注意,它们是动态的(用户定义的),表格会很大。
现在我希望获得符合某些条件的所有ID
。要返回,ID
就足以匹配每个Category
中的一个值。
例如:
给我所有IDS
的ID((LOCATION = COPENHAGEN或LOCATION = MADRID)和(GENDER = MALE))
应该返回A,B
另一个例子:
给我所有IDS
的ID((POSITION = SYSADMIN OR POSITION = WEBDESIGN) AND (GENDER = FEMALE) AND (LOCATION = COPENHAGEN OR LOCATION = MADRID))
应该返回C
返回的id将用作另一个查询的子查询 - 因此性能很重要。
更新
我已经使用示例数据创建了此sql fiddle,并提出了一个无效的解决方案。
答案 0 :(得分:2)
[删除了初始响应,因为它不起作用。在使其功能化时,我在第二次编辑中提出了查询,这是更可取的。]
您似乎正在尝试创建一个模式来跟踪在不同位置工作的人员,并且从您的数据看起来他们可能在各个办公室中拥有多个标题。以下架构允许您仅定义每个人,作业和位置一次,然后使用链接表连接它们。
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' )
这种方法称为Database Normalization,通常可以充分利用任何RDBMS中的索引,并通过避免重复数据将表中的行数保持在最低限度。
我re-fiddled your 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
我还要确保,在多个加入的可能性下,您有category
以及ID
的索引,如果不是表格中的所有3列
答案 1 :(得分:1)
目前的解决方案是为每个类别创建一个子查询。像这样:
SELECT DISTINCT ID
FROM yourtable
WHERE ID IN
(SELECT ID from yourtable WHERE (Category = 'POSITION' AND Value = 'SYSADMIN'))
AND ID IN
(SELECT ID from yourtable WHERE (Category = 'LOCATION' AND Value = 'MADRID') OR (Category = 'LOCATION' AND Value = 'COPENHAGEN'))
可以在SQL Fiddle看到工作示例。
它正在运行,但是当我有很多行或正在检查许多类别时,我担心性能。