2011-03-21 2 views
3

저는 센서스 데이터를 사용하고 있으며 이름 목록을 제공하여 레코드를 검색 할 수있는 기능을 제공하고자합니다. 이름을 알고 있거나 2 명 또는 3 명인 경우 이름이없는 모든 주소를 제외 할 수 있습니다. 이 예제 데이터 세트 고려 (주소, 가족 이름, 뒤따라야) :SQL 쿼리 질문 - 공통점을 사용하여 행 그룹을 선택하는 방법


"Janemount 하단에있는 집이 거주자 (코르크 제 4 도시 (의 일부), 코르크)", "도박", "줄리아 "
"Janemount Lower (코크 4 번 도시, 코르크)에서 "2 집 거주자", "Gamble", "Richard"
"Janemount Lower (코크 No. "Janemount Lower (Cork No. 4 Urban (일부), Cork)의 집 2", "Gamble", "Helen"


Julia, Hannah 및 Helen에 대한 검색은 공통 주소를 공유하므로 4 개의 행을 모두 반환 할 수 있어야합니다. 그것은 충분히 간단하게 들리지만, 나는 이것으로 문제가 있습니다. 데이터 세트의 크기 때문에 커서가 없어졌습니다. 어떤 아이디어?

당신이 시도 할 수

+0

"줄리아"에 대한 검색을 요청하면 4 개의 레코드를 제공해야합니까? –

+0

어떤 SQL Server 버전을 사용하고 있습니까? – Lamak

+0

"Julia"에 대한 검색을 요청하면 4 개의 레코드를 제공해야합니까? - 맞아. 그냥 줄리아가 온 가족을 그 주소로 돌려 보낼거야. –

답변

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

동일한 주소에 2 개의 줄리아 (Julia)와 한나 (Hannah)가있는 경우 결과를 반환합니다. 이것을 피하려면'COUNT (DISTINCT Forename)'이 필요합니다. –

+0

예, 답을 변경하여 답변을 드리겠습니다 ... 감사합니다. – Lamak

-1
select * 
from dataset 
where address = (
    select address 
    from dataset 
    where famly_name = 'Hannah' and forename = 'Gamble' 
) 
+1

다운 voters는 이유를 두어야한다 또는 좋은 응답을 찾는 후손을 위해 좋지 않다. 그들이 알게 될 것입니다. – richard

+0

(나는 downvote하지 않았지만 :) 이것은 오직 Hannah Gamble이라는 사람과 같은 주소를 가진 사람들을 발견 할 것입니다 (plus forename과 familyname을 교환했습니다). –

+0

@yper 8 개의 대답 각각은 요구 사항의 다른 해석에서 왔습니다. 이것은 그들 중 하나입니다. –

-1

당신은이 가정 주소가 정확하게 일치하는 것으로 시작할 수 있습니다. 당신이 가장 가능성이 일부 DUPS

Select 
    T1.* 
From 
    TableName T1 
Inner Join 
    TableName T2 
On 
    T1.Address = T2.Address 
Where 
    T1.ForeName = 'Julia' 
+1

Downvoters는 이유를 설명 할 필요가 있거나 좋은 대답을 추구하는 자손에게 좋지 않습니다. 그들이 알게 될 것입니다. – richard

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)) 
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 
; 

2 솔루션 :

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 
; 
1

이 쿼리 :

 select streetaddress, count(*) as occupantcount 
     from census 
     where firstname in ("Julia", "Hannah", "Helen") 
     group by streetaddress 
     order by occupantcount desc 

탑승자의 하나는 IN에서 제 이름 중 하나() 목록이 어디에 각 주소에서 탑승자의 어드레스 번호를 리턴하고, 최다 탑승자 투 최소 탑승자 결과를 주문 것 주문. 동일한 원칙 (주소로 그룹화)에 대한 변형은 다른 종류의 정보를 얻을 수 있습니다. 결과에 연속적인 필터를 적용하여 원하는 행에 제로 인 (zero-in) 할 수 있습니다.

+1

'HAVING COUNT (*)> = 3'을 추가하는 것은 OP가 묘사하는 것과 더 가깝습니다. –

+0

우리는 그를 물고기에게 건네지 않고 물고기를 가르치고 있습니다. 게다가 그는 HAVING()을 포함하는 연속적인 필터를 추가 할 수 있다고 덧붙였다. – Tim

+1

글쎄, 그는 큰 푸른 고래를 먹고 싶어. 파란색, 크거나 고래 인 물고기는 아닙니다. –

0

당신은 인덱스 뒤따라야과 주소이 간단하고 빠르게 할 필요가있는 경우 :

해결책 제공된 모든 이름에 공통적 인 주소를 찾기 위해 하위 쿼리를 사용하는 모든 레코드를 반환하는 것입니다
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 
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 
) 

한 가지 문제는 같은 주소에 사는 세 Hannahs가있는 경우 줄리아와 헬렌이 살고 있지 않은 경우에도 쿼리가, 그 사람들을 반환한다는 것입니다.

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 */ 

또한 필요한 경우 기준을 결합 할 수도 있습니다.