【发布时间】:2011-10-23 06:24:04
【问题描述】:
我最近一直在处理一个复杂的 SQL 查询。
我有以下表格:
[dbo].[User] ~ {ID,nickname}
[dbo].[Property] ~ {ID,title}
[dbo].[Property_Values] ~ [ID,propertyID,title}
[dbo].[Property_Values_User_Linkage] ~ {UserID,PropertyID,valueID}
它基本上是一个用户为每个属性选择值的项目。每个属性可以是单值或多值。例如,用户可以为属性 {ID=1,title=Hobbies} 选择多个值,但必须为属性 {ID=2,title=HairColor} 选择单个值。
使用另一个表 - [dbo].[Search_Property_Values_User_Linkage] - {UserID,PropertyID,valueID} 我正在选择我想要的属性并且我希望找到匹配的用户。但是,如果我没有为 HairColor 选择一个值(或多值),我应该获取所有用户(因为我不想按 HairColor 过滤)。
到目前为止,这很容易,但我似乎无法解决的问题是前面有多个值或没有用户定义的值的情况。例如,我希望所有具有 HairColor=Brown 和 Hobbies IN(basketball,football) 的用户。
我可以检索与其中一个词匹配的所有用户(以及那些具有其他属性的用户,因为我没有选择过滤它们),但我不能只获取绝对的用户符合我的标准。
要将代码转化为文字,假设我需要所有满足以下条件的用户:
- 匹配我选择的 ALL 属性值
- 可能有其他属性,例如 EyesColor,但由于我没有选择过滤值,它们也可能会被检索到。
- 可能根本没有设置任何属性,但由于我没有为该属性选择值,所以它们是有效的!
- 将所有选定的属性作为组匹配,而不仅仅是我选择的一个属性(喜欢篮球但有“红色”的用户 染发剂无效!
我遇到了一个解决方案,在该解决方案中,我创建了一个虚拟表,它按位“完成”未选择的值。例如(不是实际代码):
DECLARE @isMatches bit
SET @isMatches=0
if [propertyIsChosen]=1
{
if [userInProperty]=1 SET @isMatches=1
}
else SET isMatches=1
我基本上是与 [用户] 交叉连接 [属性]
和 LEFT-OUTER-JOIN 其余表以匹配选择。
我让所有用户和他们匹配到一个属性。这还不够好,因为我得到了棕色头发的用户,喜欢篮球/足球的用户,但没有同时匹配两者的用户(当然还有我的任何其他未定义属性)。
这很重,但这是我到目前为止分析问题的内容。
我将不胜感激。我想我在 10 年前的数学课上遗漏了一些东西......
编辑:数据库图片:http://i51.tinypic.com/2n1cfwg.png
【问题讨论】:
-
属性的数量(单个或多个值)是否固定?我的意思是以后会添加或删除属性吗?
-
请告诉我单值属性是否会随时更改为多值属性?是否所有用户都拥有相同数量的属性?此外,如果没有用户的存在,属性的存在是否有意义?我的意思是,如果还没有用户输入,那么记录说 property1:value=hobby、property2:value=children 等是否有意义?
-
是的,单值可能会变成多值。所有用户都可以选择相同的属性,但可以选择只设置少数而不是全部。是的,属性显示在用户的个人资料中,他/她可以设置这些属性,两者之间没有相对联系。谢谢!!!
-
你的外键是什么?具体来说,您是否使用识别外键(即您是否将父主键转换为子主键)?
-
当然。每个存储 propertyID 的表实际上都链接到 [dbo].[Property].[ID]。每个存储 valueID 的表实际上都链接到 [dbo].[Property_Values].[ID]。等等......但我不太明白它与我正在寻找的查询有什么关系(?)
标签: sql linkage cross-join set-theory