Получить только числовые значения из db col в sql [duplicate]

Все вышеизложенное работает ужасно с большими партиями или небольшим объемом памяти. Пришлось написать свой собственный, который будет конвейер (нигде не заметил накопления элемента):

public static class BatchLinq {
    public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int size) {
        if (size <= 0)
            throw new ArgumentOutOfRangeException("size", "Must be greater than zero.");

        using (IEnumerator<T> enumerator = source.GetEnumerator())
            while (enumerator.MoveNext())
                yield return TakeIEnumerator(enumerator, size);
    }

    private static IEnumerable<T> TakeIEnumerator<T>(IEnumerator<T> source, int size) {
        int i = 0;
        do
            yield return source.Current;
        while (++i < size && source.MoveNext());
    }
}

Изменить: Известная проблема с этим подходом заключается в том, что каждая партия должна быть перечислина и перечислина полностью, прежде чем перейти к следующей партии. Например, это не работает:

//Select first item of every 100 items
Batch(list, 100).Select(b => b.First())
116
задан reformed 17 August 2017 в 23:09
поделиться

13 ответов

Это должно работать в большинстве случаев.

SELECT * FROM myTable WHERE concat('',col1 * 1) = col1

Он не работает для нестандартных чисел, таких как

  • 1e4
  • 1.2e5
  • 123. (конечный десятичный знак)
191
ответ дан RichardTheKiwi 15 August 2018 в 14:28
поделиться
  • 1
    Спасибо. К сожалению, мне нужно признать, что 123 - это число, а 123X - нет. – Urbycoz 21 February 2011 в 12:42
  • 2
    @Urbycoz - вы пробовали? Он делает именно это – RichardTheKiwi 21 February 2011 в 12:43
  • 3
    @ Ричард. Я просто прочитал те исключения, которые ты дал. Думал, что вы имели в виду персонаж «e». Теперь я понимаю, что вы имеете в виду. – Urbycoz 21 February 2011 в 13:53
  • 4
    Также не работает для ведущих нулей, таких как 001 – Rob Gale 20 October 2012 в 00:35
  • 5
    Для конечных и ведущих нулей (например, 023.12000): concat ('', col1 * 1) = '0' ИЛИ ​​concat ('', col1 * 1) = IF (LOCATE ('.', Col1), TRIM (BOTH ' 0 'FROM col1), TRIM (LEADING' 0 'FROM col1)); – François Breton 5 June 2015 в 15:51

Я обнаружил, что это работает довольно хорошо

if(col1/col1= 1,'number',col1) AS myInfo
0
ответ дан Chris 15 August 2018 в 14:28
поделиться

Этот ответ подобен Дмитрию, но он будет содержать десятичные и положительные и отрицательные числа.

select * from table where col1 REGEXP '^[[:digit:]]+$'
6
ответ дан Devpaq 15 August 2018 в 14:28
поделиться

Я рекомендую: если ваш поиск прост, вы можете использовать `

column*1 = column

` operator interesting :) работает и быстрее, чем на полях varchar / char

SELECT * FROM myTable WHERE column * 1 = column;

ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)
3
ответ дан Ferhat KOÇER 15 August 2018 в 14:28
поделиться

использует UDF (пользовательская функция).

CREATE FUNCTION isnumber(inputValue VARCHAR(50))
  RETURNS INT
  BEGIN
    IF (inputValue REGEXP ('^[0-9]+$'))
    THEN
      RETURN 1;
    ELSE
      RETURN 0;
    END IF;
  END;

Затем, когда вы запрашиваете

select isnumber('383XXXX') 

- возвращает 0

select isnumber('38333434') 

--returns 1

select isnumber (mycol) mycol1, col2, colx from tablex; - вернет 1s и 0s для столбца mycol1

- вы можете усилить функцию, чтобы принимать десятичные значения, научную нотацию и т. д. ...

Преимущество использования UDF заключается в том, что вы можете использовать его в левой или правой части вашего сравнения «where clause». это значительно упрощает ваш SQL перед отправкой в ​​базу данных:

 SELECT * from tablex where isnumber(columnX) = isnumber('UnkownUserInput');

надеюсь, что это поможет.

3
ответ дан Hugo R 15 August 2018 в 14:28
поделиться

Все еще не хватает этой простой версии:

SELECT * FROM myTable WHERE `col1` + 0 = `col1`

(добавление должно быть быстрее как умножение)

Или самая медленная версия для дальнейшего воспроизведения:

SELECT *, 
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC` 
FROM `myTable`
HAVING `IS_NUMERIC` = 1
3
ответ дан Jirka Kopřiva 15 August 2018 в 14:28
поделиться
  • 1
    Если я не понимаю, MySQL преобразует любую строку в 0, поэтому это не будет различать строки и числа, оба возвратятся одинаково. – Ivan McA 30 November 2017 в 07:19
  • 2
    'a' + 0 = 'a' имеет значение TRUE – Paul Spiegel 14 February 2018 в 14:25

Если ваши данные являются «test», «test0», «test1111», «111test», «111»

Чтобы выбрать все записи, где данные являются простыми int:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '^[0-9]+$';

Результат: '111'

(В regex, ^ означает начало, а $ означает конец)

Чтобы выбрать все записи, где существует целое или десятичное число:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '^[0-9]+\\.?[0-9]*$'; - for 123.12

Результат: '111' (то же, что и в последнем примере)

Наконец, чтобы выбрать все записи, в которых существует номер, используйте это:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '[0-9]+';

Результат: «test0» и «test1111» и «111test» и «111»

49
ответ дан Marcus Stemple 15 August 2018 в 14:28
поделиться
  • 1
    Мне нравится этот подход лучше, потому что он более ясный и менее «хакерский». чем конкатенационный трюк. Благодаря! – CullenJ 22 October 2013 в 22:57
  • 2
    Не работает для отрицательных значений. Я бы исправил предлагаемое регулярное выражение следующим образом: REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$' – Nicolas 15 December 2015 в 11:49
  • 3
    REGEXP '^ [+ \ -]? [0-9] + \\.? [0-9] * $ - хорошее решение! – ÖMER TAŞCI 21 May 2018 в 12:29

Это решает все ваши проблемы? так как строки не будут вычисляться так же, как цифры ...

SELECT * FROM myTable WHERE sign (col1)!=0

знак окончания (0) равен нулю, но тогда вы можете ограничить свой запрос ...

SELECT * FROM myTable WHERE sign (col1)!=0 or col1=0
1
ответ дан Miguel 15 August 2018 в 14:28
поделиться
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'

Также будет соответствовать десятичным знакам (например, -1.2, +0.2, 6., 2e9, 1.2e-10 ).

Тест:

drop table if exists myTable;
create table myTable (col1 varchar(50));
insert into myTable (col1) 
  values ('00.00'),('+1'),('.123'),('-.23e4'),('12.e-5'),('3.5e+6'),('a'),('e6'),('+e0');

select 
  col1,
  col1 + 0 as casted,
  col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$' as isNumeric
from myTable;

Результат:

col1   |  casted | isNumeric
-------|---------|----------
00.00  |       0 |         1
+1     |       1 |         1
.123   |   0,123 |         1
-.23e4 |   -2300 |         1
12.e-5 | 0,00012 |         1
3.5e+6 | 3500000 |         1
a      |       0 |         0
e6     |       0 |         0
+e0    |       0 |         0
2
ответ дан Paul Spiegel 15 August 2018 в 14:28
поделиться

Попробуйте разделить / 1

select if(value/1>0 or value=0,'its a number', 'its not a number') from table
-1
ответ дан Saravanan Sachi 15 August 2018 в 14:28
поделиться

Еще одна альтернатива, которая кажется более быстрой, чем REGEXP на моем компьютере, -

SELECT * FROM myTable WHERE col1*0 != col1;

Это выберет все строки, где col1 начинается с числового значения.

5
ответ дан Stian Hvatum 15 August 2018 в 14:28
поделиться
  • 1
    Что, если значение равно нулю? – Urbycoz 3 November 2014 в 09:30
  • 2
    Правда, не получится, спасибо за наблюдение. – Stian Hvatum 3 November 2014 в 10:03
  • 3
    Думаю, вы могли бы просто добавить AND col1<>0, чтобы обработать это исключение. – Urbycoz 3 November 2014 в 10:12
  • 4
    Это правда, что он не работает для нулевых значений, но отлично работает для заполненных номеров, например. 004. Принятый ответ не работает для заполненных номеров – Abbas 15 January 2015 в 02:55
  • 5
    Я думаю, что это лучший способ проверить число. Просто нам нужно добавить инструкцию OR для проверки нуля, так как SELECT * FROM myTable WHERE col1 * 0! = Col1 ИЛИ col1 = '0'; – Binu Raman 20 April 2015 в 08:25

вы можете использовать CAST

  SELECT * from tbl where col1 = concat(cast(col1 as decimal), "")
0
ответ дан sumit 15 August 2018 в 14:28
поделиться

Вы также можете использовать регулярное выражение ... это будет выглядеть так:

SELECT * FROM myTable WHERE col1 REGEXP '^[0-9]+$';

Ссылка: http://dev.mysql.com/doc/refman/5.1/en/ regexp.html

201
ответ дан Zachary Weixelbaum 15 August 2018 в 14:28
поделиться
  • 1
    SELECT * FROM myTable WHERE col1 REGEXP '^ [0-9] + $'; – Dmitriy Kozmenko 22 March 2013 в 21:29
  • 2
    Принятый ответ действительно умный, но этот ответ более прямой, и я думаю, что это должно быть приемлемым решением. – pedromanoel 30 October 2013 в 17:50
  • 3
    В случае «не соответствует»: WHERE col1 NOT REGEXP..., а для случая, когда у вас может быть десятичная точка, используйте regex: ^[0-9\.]+$ – Robbie Averill 4 December 2013 в 01:44
  • 4
    @DmitriyKozmenko Если "номер" включает десятичные числа, тогда регулярное выражение больше не является «более прямым». и решение не предлагается в комментариях или ответе. – RichardTheKiwi 11 May 2015 в 03:28
  • 5
    Также не будет работать для научной нотации, только работает для ints – David Wilkins 20 October 2015 в 17:30
Другие вопросы по тегам:

Похожие вопросы: