我有一个非常简单的MS SQL表,其中包含以下数据(列名和数据类型):
TableId PersonName Attribute AttributeValue
(int) (nvarchar 50) (nvarchar 50) (bit)
----------- ----------------------- ------------------- --------------
1 A IsHuman 1
2 A CanSpeak 1
3 A CanSee 1
4 A CanWalk 0
5 B IsHuman 1
6 B CanSpeak 1
7 B CanSee 0
8 B CanWalk 0
9 C IsHuman 0
10 C CanSpeak 1
11 C CanSee 1
12 C CanWalk 0
现在,我需要的是具有Attribute IsHuman和CanSpeak且AttributeValue = 1的唯一PersonName。
预期结果应该是(必须不包括C,因为这个具有IsHuman = 0)
PersonName
------------
A
B
请任何专家帮我写一个SQL查询。
答案 0 :(得分:3)
SELECT PersonName
FROM MyTable
WHERE AttributeName = 'IsHuman'
AND AttributeValue = 1
INTERSECT
SELECT PersonName
FROM MyTable
WHERE AttributeName = 'CanSpeak'
AND AttributeValue = 1;
显然,如果标准可以变化,这种方法不会“扩展”。可能您需要的关系运算符是division,通常称为"the supplier who supplies all parts",特别是division with remainder。
答案 1 :(得分:2)
SELECT PersonName
FROM MyTable
WHERE (AttributeName = 'IsHuman' AND AttributeValue = 1) OR
(AttributeName = 'CanSpeak' AND AttributeValue = 1)
GROUP BY PersonName
HAVING COUNT(*) > 1
或强>
SELECT PersonName
FROM MyTable
WHERE AttributeValue = 1 AND AttributeName IN ('IsHuman', 'CanSpeak')
GROUP BY PersonName
HAVING COUNT(*) > 1
答案 2 :(得分:1)
SELECT PersonName FROM MyTable
WHERE PersonName IN
(SELECT T1.PersonName FROM MyTable T1 WHERE T1.Attribute = 'IsHuman' and T1.AttributeValue='1')
AND (Attribute = 'CanSpeak' AND AttributeValue='1')
答案 3 :(得分:0)
select personname from yourtablename where personname in ('a','b') group by personname
答案 4 :(得分:0)
我认为根据索引和表格大小,两个内部联接可能会给你带来正常的性能。
SELECT t.PersonName FROM table t
INNER JOIN table t2 ON t.PersonName=t2.PersonName AND t3.Attribute = 'IsHuman' AND t2.AttributeValue = 1
INNER JOIN table t3 ON t2.PersonName=t3.PersonName AND t3.Attribute = 'CanSpeak' AND t3.AttributeValue = 1
或
SELECT t.PersonName FROM table t
INNER JOIN table t2 ON t.PersonName=t2.PersonName
INNER JOIN table t3 ON t2.PersonName=t3.PersonName
WHERE t2.Attribute = 'IsHuman' AND t2.AttributeValue = 1 AND t3.Attribute = 'CanSpeak' AND t3.AttributeValue = 1
这个解决方案可以大大简化,但是属性IsHuman和CanSpeak是在单独的表中,它们之间有一个链接ID表。听起来像这张表可能会受益于一些规范化。
如果您无法取得进展,则视图可能有助于提高效果。我没有安装SQL,所以我无法验证任何性能方面。
答案 5 :(得分:-1)
我实际上将此作为面试的筛选问题。你们谁都不会得到这份工作。
好吧,也许你愿意,但是虽然你使用的策略可能会或可能不会起作用,但它们并不是一般化的,它们会错过关系代数的基本概念,即机智,别名。
正确的答案(在某种意义上说,它会让我更有可能雇用你,以及RDMS的优化程序理解它的重要性较低,并且可以扩展到其他任意复杂的情况)
SELECT t1.PersonName
FROM MyTable t1, MyTable t2
WHERE t2.AttributeName = 'CanSpeak'
AND t2.AttributeValue = 1
AND t1.AttributeName = 'IsHuman'
AND t1.AttributeValue = 1
AND t1.PersonName = t2.PersonName;