2009-04-23 49 views
2

有一个在纸上看起来很容易的问题,但我有一个很大的问题,弄清楚如何最好地编写单个查询。SQL查询问题。我应该使用联盟吗?

我有一个表

 
CREATE TABLE `profile_values` ( 
    `fid` int(10) unsigned NOT NULL default '0', 
    `uid` int(10) unsigned NOT NULL default '0', 
    `value` text, 
    PRIMARY KEY (`uid`,`fid`), 
    KEY `fid` (`fid`) 
) 

此表的一点是档案信息存储的用户。
例如一个典型的行会是这样的..

 
fid | uid | value 
__________________ 
1 | 77 | Mary 
11 | 77 | Poppins 
1 | 123 | Steve 
11 | 123 | Davis 

注:

 
'fid' of '1' represents the first name 
'fid' of '11' represents the last name 
'uid' is a users id within the site. 

我想实现的就是找回所有的UID满足名字的条件,如“S%”和姓氏像'D%'。
我需要这个的原因是因为我有一个网站用户的自动完成搜索框。
因此,如果我在搜索框中键入'S',我将看到以字母'S'开头的所有用户列表,如果我现在键入空格并且'D',我现在应该能够看到用户列表谁符合这两个条件。

有没有人有任何想法这可以实现? 在此先感谢。

回答

4
select firstname.uid, fistname.value, lastname.value 
from 
    profile_values firstname 
    inner join profile_values lastname 
    on firstname.uid = lastname.uid 
WHERE 
    firstname.fid = 1 
    AND lastname.fid = 11 
    AND fistname.value like 'S%' 
    AND lastname.value like 'D%' 

,或者与用户表

select users.uid, fistname.value, lastname.value 
from 
    users 
    inner join profile_values firstname 
    on firstname.uid = users.uid 
    AND firstname.fid = 1 
    inner join profile_values lastname 
    on lastname.uid = users.uid 
    AND lastname.fid = 11 
WHERE 
    fistname.value like 'S%' 
    AND lastname.value like 'D%' 

编辑:

忘了提:工会在许多DBMS执行不好。如果你需要一个联合,你的数据库模型大多数有问题。在使用union之前使用其他选择。

+0

谢谢你的提示和解决方案。赞赏:)。 这适用于所有其他人也很好回复也。 – wkmit 2009-04-23 13:40:03

2
SELECT * 
FROM profile_values pv1 
WHERE pv1.fid = 1 
     AND pv1.value LIKE 'M%' 
JOIN profile_values pv11 
ON  pv11.fid = 11 
     AND pv11.value LIKE 'D%' 
     AND pv11.uid = pv1.id 
2

加入上profile_values 两次这样的:

SELECT p1.uid 
FROM profile_values p1, profile_values p2 
WHERE p1.uid=p2.uid AND p1.fid=1 AND p2.fid=11 
    AND p1.value LIKE 'S%' 
    AND p2.value LIKE 'D%' 
+1

这是通过where子句有效创建交叉联接和筛选,而不是执行内部联接,因此性能较低 – CodeMonkey1313 2009-04-23 12:09:01

+0

@ MasterMax1313:您是对的,并且非常感谢您指出了这一点。这对于大型桌子来说当然是需要考虑的。 – 2009-04-23 13:39:14

4

还有你的表格看起来像inner-platform effect反模式的一个典型例子。

因此,不是在短期内(已经完成)回答您的问题,而是从长远的角度回答您的目标应该是更改数据库,以便名字和姓氏存储在他们自己的专栏。这些可以被索引,因此这种类型的搜索将更快,并且它们将更容易处理,因为您可以直接使用列名称。

您使用数字来引用存储在列中的数据类型的事实表明,实际使用的数据类型数量是有限的,这意味着它们可以分解为单独的列(如果空间是关心和许多值为空,那么你可以使用稀疏列)。

然后将查询只会是这样的:

select * from users where first_name like 's%' and last_name like 'd%'