似乎微不足道,但无法找到解决方案 -
我需要编写查询,根据属性值获取人员 (例如,让我有attr'1'和'2'和'3'的人)
* 澄清:可以对三个以上的属性值进行查询 - 它将由用户选择 - 从0到n值,但我不期望超过7个值... *
-- tsql script --------------
create table ##temp (person char(1), attr char(1) );
-- can be 1..n persons and 1..n attributes
insert into ##temp VALUES
('A','1'),
('A','2'),
('B','1'),
('C','2');
-- sample: get all persons which have attribute 1 AND 2
-- sample: result should be 'A' only
drop table ##temp
-- tsql script -----------------
感谢您的帮助, HH
答案 0 :(得分:5)
您可以使用带有GROUP BY
子句的HAVING COUNT(DISTINCT)
。
SELECT person
FROM ##temp
WHERE attr IN ('1', '2')
GROUP BY
person
HAVING COUNT(DISTINCT attr) = 2
以下语句将始终优于COUNT(DISTINCT)
,但如果存在重复项,则会产生不正确的结果。 请注意,优异表现可能无法衡量。
SELECT person
FROM ##temp
WHERE attr IN ('1', '2')
GROUP BY
person
HAVING COUNT(*) = 2
答案 1 :(得分:1)
您可以将表格加入到自身:
select t1.person
from ##temp t1
inner join ##temp t2 on t2.person = t1.person and t2.attr = '2'
where t1.attr = '1'
由于这需要为每个添加的属性进行另一次连接,因此它不是很灵活。另一方面,如果你添加distinct
,它也会处理重复的属性。
答案 2 :(得分:1)
正常情况下,你有一张桌子,每个人单独列出一个人, 以及带有属性的第二个表
select person from (
select person, count(person) as cnt from ##temp where attr in (1,2,3) group by person
) where cnt = 3
这应该做的工作
但在您的测试表中只有attr 1和2 ...所以这不会显示任何结果
select person from (
select person, count(person) as cnt from ##temp where attr in (1,2) group by person
) where cnt = 2
会告诉你A
答案 3 :(得分:0)
如果我理解正确并且您希望这是动态的,那么您必须使用动态sql 来构建查询
SELECT person FROM ###temp WHERE attr = '1' AND attr = '2'
使用您要搜索的数据构建 WHERE 部分。然而,由于它以查询优化的形式带来的限制,这不是一个好主意。因此,更好的方法是将 attrs 作为逗号分隔的字符串并使用split函数将其拆分。然后可以将其结果插入到另一个临时表中,并在主查询中使用,并能够保留查询分析器可以为您完成的大部分优化。
分割功能的一个例子可能是
CREATE FUNCTION dbo.Split(@String varchar(8000),
@Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
然后,您可以执行类似
的查询SELECT person
FROM ###temp
WHERE attr IN(SELECT CONVERT(int, items) FROM dbo.Split(@attrs, ','))
GROUP BY person
HAVING ( COUNT(person) = @numattrs )
@numattrs 值应该是您在搜索中使用的属性数。提供给您的程序或使用
之类的东西获取SELECT COUNT(*) FROM dbo.Split(@attrs, ',')
祝你好运!
答案 4 :(得分:0)
我认为这样做不会有所帮助:
SELECT person FROM ###temp WHERE attr = '1' AND attr = '2'
没有attr值永远是1和2同时!!
如果你使你的attr字段bigint,并使用二进制值1,2,4,8,16等,那么
select person from table group by person having sum (attr) = 3
会找到人的条目为1,条目为2(完全)。 类似地
having sum(attr) | 11
表示它包括1,2和8以及其他人。查找按位函数OR,AND NOT等
注意这受bigint的限制,即你可以有大约63个不同的attr值。