views:

59

answers:

3

For example:

SELECT COUNT(ID) FROM My_Table
WHERE ID < 

(SELECT ID FROM My_Table
WHERE ID LIKE '%4'
ORDER BY ID LIMIT 1)    

My_Table:

  X          ID    Y     
------------------------
|      |     A1  |     |
------------------------
|      |     B2  |     |
------------------------
|      |     C3  |     |
------------------------ -----Page 1
|      |     D3  |     |
------------------------
|      |     E3  |     |
------------------------
|      |     F5  |     |
------------------------ -----Page 2
|      |     G5  |     |
------------------------
|      |     F6  |     |
------------------------
|      |     G7  |     | -----Page 3

There is no data ending in 4 but there still are 5 rows that end in something less than "%4".

However, in this case were there is no match, so SQLite only returns 0

I get it is not there but how do I change this behavior to still return number of rows before it, as if it was there?

Any suggestions?

Thank You.

+1  A: 
SELECT COUNT(ID) FROM My_Table
WHERE ID < (SELECT ID FROM My_Table
  WHERE SUBSTRING(ID, 2) >= 4
ORDER BY ID LIMIT 1)   
Paulo Scardine
Note SUBSTRING may be different in your platform.
Paulo Scardine
@Paulo Scardine: What if staring "pos" is not always 2? and is dynamic? Is there any way to do this with specifying a starting position?
Tommy
@Tommy: Yes, starting position can be an expression.
Unreason
@Tommy: I made a serie of assumptions based in your sample data. Send a more accurate sample and I will be happy to sugest a more accurate answer.
Paulo Scardine
@Paulo Scardine: Each data is a char[40] containing alphas and numerals in any order. The user can do a wild card search; %Id4 or %Time7%, etc. So in the case there is nothing matching, I want find the row that would come before (or after) the one he is looking for. I'm confused because the search can be any part of the string...and not sure how I would know what the next row would be?
Tommy
@Tommy: I don't think your first approach is viable using pure SQL. What I would suggest is using some similarity algorithm, like n-gram, to classify your data and show answers ordered according. See http://en.wikipedia.org/wiki/N-gram
Paulo Scardine
+1  A: 

Assuming there is always one letter before the number part of the id field, you may want to try the following:

SELECT COUNT(*) FROM my_table WHERE CAST(substr(id, 2) as int) <= 4;

Test case:

CREATE TABLE my_table (id char(2));

INSERT INTO my_table VALUES ('A1');
INSERT INTO my_table VALUES ('B2');
INSERT INTO my_table VALUES ('C3');
INSERT INTO my_table VALUES ('D3');
INSERT INTO my_table VALUES ('E3');
INSERT INTO my_table VALUES ('F5');
INSERT INTO my_table VALUES ('G5');
INSERT INTO my_table VALUES ('F6');
INSERT INTO my_table VALUES ('G7');

Result:

5

UPDATE: Further to the comment below, you may want to consider using the ltrim() function:

The ltrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the left side of X.

Example:

SELECT COUNT(*) 
FROM   my_table 
WHERE  CAST(ltrim(id, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') as int) <= 4;

Test case (adding to the above):

INSERT INTO my_table VALUES ('ABC1');
INSERT INTO my_table VALUES ('ZWY2');

New Result:

7
Daniel Vassallo
@Daniel Vassallo: what is the best way to handle when it is not always 2?
Tommy
@Tommy: Updated my answer with another possible solution.
Daniel Vassallo
@Daniel Vassallo: Thank You, let me give ltrim a try....
Tommy
+1  A: 

In MySQL that would be:

SELECT  COUNT(ID)
FROM    My_Table
WHERE   ID < 
        (
        SELECT  id
        FROM    (
                SELECT  ID
                FROM    My_Table
                WHERE   ID LIKE '%4'
                ORDER BY
                        ID
                LIMIT 1
                ) q
        UNION ALL
        SELECT  MAX(id)
        FROM    mytable
        LIMIT 1
        )  
Quassnoi
@Quassnoi: This seems to only return the greatest value in the whole row?
Tommy