0

I have a table as follows:

create table table1(id integer,firstname text,lastname text);

id firstname lastname

====================
1 ben taylor
2 rob taylor
3 rob smith
4 rob zombie
5 peter smith
6 ben smith
7 peter taylor

Now I have another table create table table2(id integer,position integer);

id position

===========
1 5
1 9
2 6
3 7
6 2

I want to select rows with a lastname , where the lastname must be shared by ben and rob and firstnames must be ben and rob.
Now I also want the position of ben to be one lesser than that of rob, hence the result would be :

id firstname lastname position

===========================
1 ben taylor 5
2 rob taylor 6

What should the sql query be ?

3 Answers 3

2

To get the last name:

select lastname
from names n join
     position p
     on n.id = p.id
where firstname in ('ben', 'rob')
group by lastname
having count(distinct firstname) = 2 and
       1+max(case when firstname = 'ben' then p.position end) = max(case when firstname = 'rob' then p.position end)

You can then get the original list with:

select n.*, p.position
from names n join
     position p
     on n.id = p.id
where firstname in ('ben', 'rob') and
      lastname in (select lastname
                   from names n join
                        position p
                        on n.id = p.id
                   where firstname in ('ben', 'rob')
                   group by lastname
                   having count(distinct firstname) = 2 and
                          1+max(case when firstname = 'ben' then p.position end) = max(case when firstname = 'rob' then p.position end)
                  )

I think the following query answers your question, with the caveat that this combines the names into one row:

select nben.*, p.position, nrob.*, prob.position
from names nben join
     positions p
     on nben.id = p.id and
        nben.firstname = 'ben' join
     names nrob
     on nrob.firstname = 'rob' and
        nrob.lastname = nben.lastname join
     positions prob
     on nrob.id = prob.id and
        p.position = prob.position - 1

Also, this is untested.

Sign up to request clarification or add additional context in comments.

8 Comments

This query outputs all three taylors, and the smiths.
the result i am looking for is written at the end of the question.
Sorry about that . . . I totally missed the condition on positions. I put in one fix for that, assuming there is only one position per name.
This doesn't output anything.
there can be many positions per name as in example ben taylor is at position 5 and 9,but ben taylor at position 5 is in the result
|
0

This gives me the result i needed obtained from Gordon Linoff's solution:
select * from(select n.*, p.position
from names n join
position p
on n.id = p.id
where firstname in ('ben', 'rob') and
lastname in (select lastname
from names n join
position p
on n.id = p.id
where firstname in ('ben', 'rob')
group by lastname
having count(distinct firstname) = 2

              )
         )

as x,names,position
where
(x.id!=names.id and names.id=position.id and names.lastname=x.lastname
and (x.firstname='rob' and names.firstname='ben') and x.position=position.position+1)
or
(x.id!=names.id and names.id=position.id and names.lastname=x.lastname
and (x.firstname='ben' and names.firstname='rob') and x.position+1=position.position)


Comments

-1

Gordon Linoff's solutions:
select nben.*, p.position
from names nben join
positions p
on nben.id = p.id and
nben.firstname = 'ben' join
names nrob
on nrob.firstname = 'rob' and
nrob.lastname = nben.lastname join
positions prob
on nrob.id = prob.id and
p.position = prob.position - 1

gives same result as:

select * from(select n.*, p.position
from names n join
position p
on n.id = p.id
where firstname in ('ben', 'rob') and
lastname in (select lastname
from names n join
position p
on n.id = p.id
where firstname in ('ben', 'rob')
group by lastname
having count(distinct firstname) = 2

          )
     )

as x,names,position
where (x.id!=names.id and names.id=position.id
and names.lastname=x.lastname
and (x.firstname='ben' and names.firstname='rob')
and x.position+1=position.position)

1 Comment

In the two of Gordon Linoff's solutions i edited, which one is more efficient and suitable if the size of the tables are big with size in several gigabytes?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.