2


id | apples  | oranges
1    111       p
2    112       p
3    113       p
4    113       f
5    113       -
6    114       p
7    114       f
8    115       -
9    115       -
10   116       f

Looking for a way to return only the rows where:

  1. oranges contains value 'f' or no value (empty)
  2. there are duplicate values in apples
  3. at least one duplicate in applies contains value of 'p' in oranges.

The rows 4,5 & 7 in bold and italic are what I am after.

2
  • 1
    maybe it is just my eyes, but none of those things are in bold Commented Nov 5, 2012 at 15:45
  • @Woot4Moo It's your eyes, although the bold doesn't stand out that much to be honest. Look really closely. Commented Nov 5, 2012 at 15:46

2 Answers 2

1

You need to do a self-join. Something like this:

SELECT t1.*
FROM myTable t1
INNER JOIN myTable t2 ON t1.apples = t2.apples
WHERE t1.oranges IN ('f', '-')
AND t2.oranges = 'p'

SQL Fiddle example

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

6 Comments

SQL Fiddle is awesome! (didn't know it)
Why AND t2.oranges = 'p'? I think this isn't what the op wants
well the p part is for when dupes are found in apples
@MahmoudGamal From the question: "and at least one duplicate contains value of 'p' in oranges". So if we have one duplicate that satisfies this condition, we don't have to check for other duplicates and likewise if this condition is not satisfied, we do not care if there are 100 other duplicates. Therefore we can simplify the query to only this check.
I checked the SQL fiddle example and it works. Thank you. When trying this on a table with nearly a million records it takes way too long so I'll need to find a way to break this down.
|
0

Lets write these as three separate queries and then combine them.

Looking for a way to return only the rows where oranges contains value 'f' or no value (empty)

select *   
from table  
where oranges = 'f'
or oranges is null;

where there are duplicate values in apples and at least one duplicate contains value of 'p' in oranges

select * 
( 
  select *
  from table    
  INNER JOIN (SELECT apples FROM inner_table
  GROUP BY apples HAVING count(id) > 1)
)
where oranges ='p'

And then you can combine them like so:

select *
(
    select *  
    from table  
    where (oranges ='f' or oranges is null)  
    INNER JOIN (SELECT apples FROM inner_table
  GROUP BY apples HAVING count(id) > 1)
)
where oranges ='p'

This is untested since I don't have a schema to work from.

2 Comments

I understood the question to mean table and inner_table are one in the same.
they are the same logical table, they are named to illustrate the variable that holds the temporary name. A lot of my time is in Oracle lately so the syntax may look hokey.

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.