views:

114

answers:

4

I have the following SQL query:

SELECT Phrases.*
FROM Phrases
WHERE (((Phrases.phrase) Like "*ing aids*") 
  AND ((Phrases.phrase) Not Like "*getting*") 
  AND ((Phrases.phrase) Not Like "*contracting*")) 
  AND ((Phrases.phrase) Not Like "*preventing*"); //(etc.)

Now, if I were using RegEx, I might bunch all the Nots into one big (getting|contracting|preventing), but I'm not sure how to do this in SQL.

Is there a way to render this query more legibly/elegantly?

A: 

Depending on what SQL server you are using, it may support REGEX itself. For example, google searches show that SQL Server, Oracle, and mysql all support regex.

Dave
+4  A: 

Just by removing redundant stuff and using a consistent naming convention your SQL looks way cooler:

SELECT *
FROM phrases
WHERE phrase     LIKE '%ing aids%'
  AND phrase NOT LIKE '%getting%'
  AND phrase NOT LIKE '%contracting%' 
  AND phrase NOT LIKE '%preventing%'

You talk about regular expressions. Some DBMS do have it: MySQL, Oracle... However, the choice of either syntax should take into account the execution plan of the query: "how quick it is" rather than "how nice it looks".

Álvaro G. Vicario
I'm not so much looking for performance -- I'm running handwritten queries on a fixed dataset, to try to remove irrelevant data -- as I am looking for a simple way to add more and more refinements till I find the information I need.As such, in the example above, I keep adding another gerund that I want to keep out of the results, and thought perhaps there's a more efficient way than adding a whole line.
Jono
Well, it's not pretty like a regex, but it works in Access. Thanks.
Jono
+1  A: 

With MySQL, you're able to use regular expression where-clause parameters:

SELECT something FROM table WHERE column REGEXP 'regexp'

So if that's what you're using, you could write a regular expression string that is possibly a bit more compact that your 4 like criteria. It may not be as easy to see what the query is doing for other people, however.

It looks like SQL Server offers a similar feature.

Kaleb Brasee
+1  A: 

Sinec it sounds like you're building this as you go to mine your data, here's something that you could consider:

CREATE TABLE Includes (phrase VARCHAR(50) NOT NULL)
CREATE TABLE Excludes (phrase VARCHAR(50) NOT NULL)

INSERT INTO Includes VALUES ('%ing aids%')
INSERT INTO Excludes VALUES ('%getting%')
INSERT INTO Excludes VALUES ('%contracting%')
INSERT INTO Excludes VALUES ('%preventing%')

SELECT
     *
FROM
     Phrases P
WHERE
     EXISTS (SELECT * FROM Includes I WHERE P.phrase LIKE I.phrase) AND
     NOT EXISTS (SELECT * FROM Excludes E WHERE P.phrase LIKE E.phrase)

You are then always just running the same query and you can simply change what's in the Includes and Excludes tables to refine your searches.

Tom H.
That's an interesting approach. I'm guessing there's no simpler solution with an array variable in SQL, though, is there.
Jono
Hmm.I'm really beginning to like this.
Jono
Okay, trying to implement this, I've found a problem -- I can't do any ORs there. So I can't combine things. For example, finding 'art' and ('school' or 'degree') but not 'part'.
Jono
You could add a bit column to the Includes table for required or optional terms. Then just get a count of how many of those rows are matched for each type. The required count would have to match the count of required terms for the search and the overall count would have to be at least one. If I have time later I'll try to put together a query, but maybe this can get you started.
Tom H.