Reputation: 1106
I'm having trouble building a specific query to select records. Here is a dumbed down example of what I'm trying to achieve.
Let's say I have a table called Criteria
that looks something like this:
ID Unit Product Part
== ======== ======= ========
1 'sports' 'bike' 'handle'
2 'sports' ' ' ' '
3 'furn' 'couch' ' '
etc.
And I have a table called Entries
that looks something like this:
ID Tuple
== =========================
1 'sports / bike / seat'
2 'sports / racket / frame'
3 'furn / desk / leg'
4 'furn / lamp / shade'
etc.
Record 1 in Criteria
suggests that any tuple that is "sports / bike / handle" qualifies. Record 2 in Criteria
, where the Product
and Part
contain spaces, suggests that any tuple beginning with 'sports' qualifies ("sports / % / %"). Record 3 suggests that any tuple beginning with 'furn' and 'couch' qualifies ("furn / couch / %"). I want to select all the records that don't qualify for any of the criteria.
In this case, records 3 and 4 from Entries
should be returned, because they don't match any of the given criteria.
I'm new to SQL, so I'm having trouble coming up with a suitable query. My thought process is along these lines:
For each record of Criteria
, build a string comparison string based on the Unit
, Product
, and Part
. For record 1, for example, the string would be 'sports / bike / handle'. For record 2, the string would be 'sports / % / %', and for record 3: 'furn / couch / %'. Now, select all records where Tuple
does not equal any of those strings. I'm having trouble translating this into SQL terms, and that is where I need your help.
Upvotes: 0
Views: 1586
Reputation: 1269873
You can do this with an outer join, using like:
select e.*
from Entries e left outer join
(select c.*,
((case when c.unit = ' ' then '%' else c.unit end) + ' / ' +
(case when c.product = ' ' then '%' else c.product end) + ' / ' +
(case when c.part = ' ' then '%' else c.part end)
) as likestr
from Criteria c
) c
on e.tuple like likestr
where c.id is null
This will be an expensive operation, but should do what you want.
The data structure would make more sense if you stored the components of the tuple in separate columns. Then you could do a column-by-column comparison.
Upvotes: 2
Reputation: 74277
Why are you storing data like that? Inquiring minds want to know.
However, you might try something along these lines:
select *
from entries e
where not exists ( select *
from criteria c
where e.tuple like case coalesce( unit , '' ) when '' then '%' else unit end
+ ' / ' + case coalesce( product , '' ) when '' then '%' else product end
+ ' / ' + case coalesce( part , '' ) when '' then '%' else part end
)
Ugly, but gits 'er done.
Upvotes: 2