对于非常简单的表结构,即。人,标准和人标准 (组合表),我现在设置了一个查询,选择所有拥有所有选定标准的人。
此时查询本身看起来像这样:
SELECT
p.PersonID
FROM
Person p,
( SELECT DISTINCT PersonID, CriteriaID
FROM PersonCriteria
WHERE CriteriaID in (#list_of_ids#)
) k
WHERE
p.PersonID= k.PersonID
GROUP BY
p.PersonID
HAVING
Count(*) = #Listlength of list_of_ids#
到目前为止没有问题,一切正常。
现在我想为用户提供在搜索中添加一些AND和OR变量的可能性,即。有人可以说:
我正在寻找一个拥有:标准1和3和4的人 (将由上述查询涵盖)和(5 OR 6或7)和(8或9)等等...
我不知道从哪个附加级别开始。我希望别人能做.. :-)
答案 0 :(得分:2)
我不得不说 - 我很难过。我想不出任何可能接近的解决方案。我会尝试在这些方向寻找解决方案:
<强>加了:强>
啊,我想我明白了!虽然我认为表现会很糟糕。但这会奏效!例如,如果您需要搜索1 AND 2 AND (3 OR 4)
,那么您可以写:
SELECT
*
FROM
Persons A
WHERE
EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=1)
AND
EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=2)
AND
(
EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=3)
OR
EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=4)
)
已添加2:这是另一个,但性能可能更差:
SELECT p.* FROM Person p
JOIN (select PersonID from PersonCriteria WHERE CriteriaID=1) c1 ON p.PersonID=c1.PersonID
JOIN (select PersonID from PersonCriteria WHERE CriteriaID=2) c2 ON p.PersonID=c2.PersonID
JOIN (select PersonID from PersonCriteria WHERE CriteriaID IN (3,4)) c3 ON p.PersonID=c3.PersonID
已添加3:这是第2号的变体,但这可能实际上有可能获得不错的表现!
SELECT p.* FROM
Person p
JOIN PersonCriteria c1 on (p.PersonID=c1.PersonID AND c1.CriteriaID=1)
JOIN PersonCriteria c2 on (p.PersonID=c2.PersonID AND c2.CriteriaID=2)
JOIN PersonCriteria c3 on (p.PersonID=c3.PersonID AND c3.CriteriaID IN (3,4))
如果你在列(PersonID,CriteriaID)上添加一个索引给PersonCriteria(完全按照这个顺序!),那么我认为它的速度和你在任何情况下的速度一样快。
答案 1 :(得分:1)
您可以对此进行简化,例如:
SELECT DISTINCT 是PersonID 来自PersonCriteria 哪里 CriteriaID IN(1,2)OR CriteriaID IN(8,9)
还考虑使用JOIN而不是子选择(用于性能)
答案 2 :(得分:1)
我明白你的要求这应该有效。我不能保证我理解你的要求,但很明显有几个人已经有不同的解释。
SELECT p.PersonID
FROM Person p
JOIN
(SELECT DISTINCT PersonID
FROM PersonCriteria
WHERE CriteriaID in (1,2,3) and count(criteriaID) = 3) k
on p.PersonID = k.PersonID
JOIN
(SELECT DISTINCT PersonID
FROM PersonCriteria
WHERE CriteriaID in (4,5) ) k2 on p.PersonID = k2.PersonID
JOIN
(SELECT DISTINCT PersonID
FROM PersonCriteria
WHERE CriteriaID in (5,6,7) ) k3 on p.PersonID = k3.PersonID
JOIN
(SELECT DISTINCT PersonID
FROM PersonCriteria
WHERE CriteriaID in (8,9) ) k4 on p.PersonID = k4.PersonID
我解释这个的方式。第一个连接是一个派生表,它可以获得具有所有三个指定条件的任何人。随后的派生表通过加入其他派生表来找到满足其中一个条件(基本上是OR部分)的人,我们完成了查询的AND部分。我也知道语法通过了SQL Server的语法检查,可能需要调整MYSQL。
答案 3 :(得分:0)
如果你需要提供一种更“动态”的方法来搜索你的数据,那么SQL会变得非常丑陋和冗长,并且不会真正完全动态......我是否提到“丑陋”?
我使用ORM框架完成任务,他们处理的工作非常棒。
但是如果您的结构只是如您所描述的那样(使用OR包装许多AND条件),那么假设您当前的AND-only实现位于名为dbo.getPersonForAndCriteria(...)
的UDF中,您可以简单地使用{{ 1}}:
UNION
注意:这只是说明性的,但我会将您的过程包装成一个好的UDF,它将参数列表(ID)作为一个表(使用XML或逗号分隔的字符串,然后在UDF中解析),然后在这个列表/表上而不是dbo.getPersonForAndCriteria(@myListOfIDs1) --// works for AND
UNION -- replaces OR
dbo.getPersonForAndCriteria(@myListOfIDs2) --// works for AND
UNION -- replaces OR
dbo.getPersonForAndCriteria(@myListOfIDs3) --// works for AND
部分做一个很好的JOIN,最后一部分变成COUNT(*)= COUNT(SELECT ID FROM myFilterTable)。