How to check if a value is a number in SQLite

后端 未结 9 1962
-上瘾入骨i
-上瘾入骨i 2020-12-10 14:29

I have a column that contains numbers and other string values (like \"?\", \"???\", etc.)

Is it possible to add an \"is number\" condition to the where clause in SQL

相关标签:
9条回答
  • 2020-12-10 15:11

    You can use the result of the function CAST( field as INTEGER) for numbers greater than zero and the simple condition like '0' per numbers equal to zero

    SELECT *
    FROM tableName
    WHERE CAST(fieldName AS INTEGER) > 0
    UNION
    SELECT *
    FROM tableName
    WHERE fieldName like '0';
    
    0 讨论(0)
  • 2020-12-10 15:11

    This answer is comprehensive and eliminates the shortcomings of all other answers. The only caveat is that it isn't sql standard... but neither is SQLite. If you manage to break this code please comment below, and I will patch it.

    Figured this out accidentally. You can check for equality with the CAST value.

    CASE   {TEXT_field}
        WHEN CAST({TEXT_field} AS INTEGER)                THEN 'Integer'     -- 'Number'
        WHEN CAST({TEXT_field} AS REAL)                   THEN 'Real'        -- 'Number'
        ELSE                                                   'Character'
    END
    

    OR

    CASE   
        WHEN {TEXT_field} = CAST({TEXT_field} AS INTEGER) THEN 'Integer'     --'Number'
        WHEN {TEXT_field} = CAST({TEXT_field} AS Real)    THEN 'Real'        --'Number'
        ELSE                                                   'Character'
    END
    

    (It's the same thing just different syntax.)

    • Note the order of execution. REAL must come after INTEGER.
    • Perhaps their is some implicit casting of values prior to checking for equality so that the right-side is re-CAST to TEXT before comparison to left-side.

    Updated for comment: @SimonWillison
    I have added a check for 'Real' values
    '1 frog' evaluated to 'Character' for me; which is correct
    '0' evaluated to 'Integer' for me; which is correct

    I am using SQLite version 3.31.1 with python sqlite3 version 2.6.0. The python element should not affect how a query executes.

    0 讨论(0)
  • 2020-12-10 15:12

    As SQLite and MySQL follow the same syntax and loose datatypes.

    The query below is also possible

    SELECT 
       <data>
     , (
         LENGTH(CAST(<data> AS UNSIGNED))
       )
         =
      CASE WHEN CAST(<data> AS UNSIGNED) = 0
      THEN CAST(<data> AS UNSIGNED)
      ELSE (LENGTH(<data>)
      ) END AS is_int;
    

    Note the <data> is BNF you would have the replace those values.

    This answer is based on mine other answer

    Running SQLite demo

    0 讨论(0)
  • 2020-12-10 15:15

    You could try something like this also:

    select * from mytable where printf("%d", field1) = field1;
    

    In case your column is text and contains numeric and string, this might be somewhat helpful in extracting integer data.

    Example:

    CREATE TABLE mytable (field1 text);
    insert into mytable values (1);
    insert into mytable values ('a');
    
    select * from mytable where printf("%d", field1) = field1;
    field1
    ----------
    1
    
    0 讨论(0)
  • 2020-12-10 15:16

    From the documentation,

    The typeof(X) function returns a string that indicates the datatype of the expression X: "null", "integer", "real", "text", or "blob".

    You can use where typeof(mycolumn) = "integer"

    0 讨论(0)
  • 2020-12-10 15:18

    For integer strings, test whether the roundtrip CAST matches the original string:

    SELECT * FROM mytable WHERE cast(cast(mycolumn AS INTEGER) AS TEXT) = mycolumn
    

    For consistently-formatted real strings (for example, currency):

    SELECT * FROM mytable WHERE printf("%.2f", cast(mycolumn AS REAL)) = mycolumn
    

    Input values:

    • Can't have leading zeroes
    • Must format negatives as -number rather than (number).
    0 讨论(0)
提交回复
热议问题