我正在处理人口普查数据,我希望通过提供名单列表来提供搜索记录的功能。这个想法是,如果您知道名称或2或3个家庭成员,您将能够排除所有没有这些名称的地址。请考虑此示例数据集(地址,姓氏,名称):
“在Janemount Lower(Cork No. 4 Urban(部分),Cork)的房子2的居民”,“赌博”,“Julia”
“Janemount Lower(Cork No. 4 Urban(部分),科克)的房子2的居民”,“赌博”,“理查德”
“在Janemount Lower(Cork No. 4 Urban(部分),Cork)的房子2的居民”,“赌博”,“Hannah”
“住在Janemount Lower(Cork No. 4 Urban(部分),科克)的房子2”,“赌博”,“海伦”
搜索Julia,Hannah和Helen应该能够返回所有4行,因为它们共享一个公共地址。这听起来很简单,但我遇到了这个问题。由于数据集的大小,游标已经不存在了。有什么想法吗?
(不用说,我已经简化了这一点,因为我现在忽略了搜索中的姓氏部分)
答案 0 :(得分:1)
你可以试试这个:
SELECT A.*
FROM YourTable A
JOIN ( SELECT Address, COUNT(*) Quant
FROM YourTable
WHERE Forename IN ('Julia','Hannah','Helen')
GROUP BY Address
HAVING COUNT(DISTINCT Forename) > 2) B
ON A.Address = B.Address
答案 1 :(得分:1)
这是relational divisio n问题。
SELECT Address, FamilyName, Forename
FROM YourTable
WHERE Address IN (SELECT Address
FROM YourTable
WHERE Forename IN ( 'Julia', 'Hannah', 'Helen' )
GROUP BY Address
HAVING COUNT(DISTINCT Forename) = 3)
或者
WITH Names(name)
AS (SELECT 'Julia'
UNION ALL
SELECT 'Hannah'
UNION ALL
SELECT 'Helen')
SELECT Address,
FamilyName,
Forename
FROM YourTable y1
WHERE NOT EXISTS (SELECT *
FROM Names n
WHERE NOT EXISTS(SELECT *
FROM YourTable y2
WHERE y1.Address = y2.Address
AND y2.Forename = n.Name))
答案 2 :(得分:1)
此查询:
select streetaddress, count(*) as occupantcount
from census
where firstname in ("Julia", "Hannah", "Helen")
group by streetaddress
order by occupantcount desc
将返回每个地址中占用者的地址和数量,只要其中一个占用者具有IN()列表中的一个名字,并按最大占用者到最少占用者顺序排序结果。对同一原则的变化(按地址分组)可以为您提供其他类型的信息。您可以对结果应用连续的过滤器,以便在所需的行上进行调零。
答案 3 :(得分:0)
SELECT t.address
, t.familyname
, t.forename
FROM yourTable t
WHERE t.address IN
-- search subquery
( SELECT s1.address
FROM yourTable s1
JOIN yourTable s2
ON s2.address = s1.address
JOIN yourTable s3
ON s3.address = s1.address
WHERE s1.forename = "Julia"
AND s2.forename = "Hannah"
AND s3.forename = "Helen"
)
ORDER BY t.address
, t.familyname
, t.forename
;
第二个解决方案:
SELECT t.address
, t.familyname
, t.forename
FROM yourTable t
WHERE EXISTS
-- search subquery
( SELECT *
FROM yourTable s1
JOIN yourTable s2
ON s2.address = s1.address
JOIN yourTable s3
ON s3.address = s1.address
WHERE s1.forename = "Julia"
AND s2.forename = "Hannah"
AND s3.forename = "Helen"
AND s1.address = t.address
)
ORDER BY t.address
, t.familyname
, t.forename
;
第3个解决方案:
SELECT t.address
, t.familyname
, t.forename
FROM yourTable t
WHERE -- search subqueries
EXISTS
( SELECT *
FROM yourTable s1
WHERE s1.forename= "Julia"
AND s1.address = t.address
)
AND EXISTS
( SELECT *
FROM yourTable s2
WHERE s2.forename = "Hannah"
AND s2.address = t.address
)
AND EXISTS
( SELECT *
FROM yourTable s3
WHERE s3.forename = "Helen"
AND s3.address = t.address
)
ORDER BY t.address
, t.familyname
, t.forename
;
答案 4 :(得分:0)
如果你索引forename和地址,这应该是直截了当的:
SELECT a.Address as CommonAddress
FROM (SELECT Address FROM Names WHERE Forename = 'Julia') a
INNER JOIN (SELECT Address FROM Names WHERE Forename = 'Richard') b ON a.Address=b.Address
INNER JOIN (SELECT Address FROM Names WHERE Forename = 'Helen') c on b.Address=c.Address
答案 5 :(得分:0)
解决方案是使用子查询查找所有提供的名称共有的地址,并返回该地址的所有记录。
declare @people table (
address varchar(255),
familyName varchar(255),
forename varchar(255)
)
insert into @people
values ('Residents of a house 2 in Janemount Lower (Cork No. 4 Urban (part of), Cork)', 'Gamble', 'Julia')
insert into @people
values ('Residents of a house 2 in Janemount Lower (Cork No. 4 Urban (part of), Cork)', 'Gamble', 'Richard')
insert into @people
values ('Residents of a house 2 in Janemount Lower (Cork No. 4 Urban (part of), Cork)', 'Gamble', 'Hannah')
insert into @people
values ('Residents of a house 2 in Janemount Lower (Cork No. 4 Urban (part of), Cork)', 'Gamble', 'Helen')
insert into @people
values ('Residents of a house 2 somewhere else (Cork No. 4 Urban (part of), Cork)', 'Cooper', 'Helen')
select people.*
from @people as people
where people.address in (
select address
from @people
where forename in ('Julia', 'Hannah', 'Helen')
group by address
having count(forename) >= 3 -- This must be equal to the number of names searched for
)
这个解决方案的一个问题是,如果有三个汉娜住在同一个地址,那么即使朱莉娅和海伦不住在那里,查询也会归还那些人。
答案 6 :(得分:0)
DECLARE @namecount int;
DECLARE @forenames TABLE (name varchar(50));
INSERT INTO @forenames
VALUES ('...'),
('...'),
('...');
SELECT @namecount = COUNT(*) FROM @forenames;
/* list all people by addresses that are shared by people
whose forenames are included in @forenames */
SELECT cd.*
FROM CensusData cd
INNER JOIN (
SELECT d.Address
FROM CensusData d
INNER JOIN @forenames f ON d.Forename = f.Name
GROUP BY d.Address
HAVING COUNT(DISTINCT d.Forename) >= @namecount
) filter ON cd.Address = filter.Address
/* same for family names */
SELECT cd.*
FROM CensusData cd
INNER JOIN (
SELECT d.[Family Name]
FROM CensusData d
INNER JOIN @forenames f ON d.Forename = f.Name
GROUP BY d.Address
HAVING COUNT(DISTINCT d.Forename) >= @namecount
) filter ON cd.[Family Name]= filter.[Family Name]
/* and so on fro other criteria */
如果需要,您还可以组合标准。
答案 7 :(得分:-1)
select *
from dataset
where address = (
select address
from dataset
where famly_name = 'Hannah' and forename = 'Gamble'
)
答案 8 :(得分:-1)
你可以从这样的事情开始,假设地址要完全匹配。它需要调整,因为你很可能会看到一些重复
Select
T1.*
From
TableName T1
Inner Join
TableName T2
On
T1.Address = T2.Address
Where
T1.ForeName = 'Julia'