Использование MIN для чисел, которые являются текстовыми типами данных?

#sql #sqlite

#sql #sqlite

Вопрос:

Я понимаю, что это плохой дизайн таблицы (не мой).

Допустим, кто-то хочет использовать MIN (Biweekly_High_Rate), исключая 0.00

  -------------------- 
| Biweekly_High_Rate |
 -------------------- 
| $0.00              |
| $15.00             |
| $25.00             |
| $50.00             |
| $100.00            |
| $100.00            |
| $200.00            |
| $500.00            |
| $0.00              |
| $10630.00          |
| $9175.00           |
| $4142.00           |
| $5242.00           |
| $3293.00           |
| $4496.00           |
| $4676.00           |
| $4762.00           |
| $11255.00          |
| $10376.00          |
| $9096.00           |
| $9456.00           |
| $9641.00           |
| $7392.00           |
| $7687.00           |
| $7835.00           |
 -------------------- 
  

Выполняется

 Select min(Biweekly_high_Rate)
From salary_range_by_job_classification
Where (biweekly_high_Rate != "$0.00");
  

ВОЗВРАТ

  ------------------------- 
| min(Biweekly_high_Rate) |
 ------------------------- 
| $100.00                 |
 ------------------------- 
  

Где это должно быть $ 15,00

Теперь я понимаю, почему это происходит. Вопрос в том, как выполнить запрос, чтобы вернуть $ 15,00?

Комментарии:

1. Какую СУБД вы используете? (Некоторые из них имеют параметры сортировки с учетом чисел.)

2. Не совсем уверен … это какой-то интерактивный онлайн-курс. давайте просто скажем, что его SQLite

3. Вы должны извлечь числовую часть из строки.

4. к сожалению, они этому еще не научили. Я попробую погуглить

Ответ №1:

Вы можете использовать комбинацию двух функций, сначала обрезать знак доллара, а затем преобразовать оставшуюся часть в число :

 SELECT MIN(CAST(LTRIM(Biweekly_high_Rate,'$') AS DECIMAL)) 
  FROM t
 WHERE CAST(LTRIM(Biweekly_high_Rate,'$') AS DECIMAL)!=0
  

Demo

Ответ №2:

Один из методов — упорядочить по длине, а затем по значению, а затем ограничить значение одной строкой:

 Select Biweekly_high_Rate
From salary_range_by_job_classification
Where biweekly_high_Rate <> '$0.00'
order by length(Biweekly_high_Rate) asc, Biweekly_high_Rate asc
limit 1;
  

Это работает, потому что строки имеют одинаковый формат — начальный '$' и два десятичных знака.

Обратите внимание: некоторые базы данных используют len() , а некоторые используют length() для длины строки.

Комментарии:

1. это хороший трюк, и я ценю ответ. Я просто смущен, почему в курсе говорится, что он начал запрос для меня с использованием MIN (bieweekly_high_rate), и я должен фильтровать его, когда это так сложно сделать, поэтому предполагается, что это лекция по основам. Либо это был плохой дизайн вопроса, либо я чего-то не хватает.

Ответ №3:

Попробуйте это: …

 WITH
-- your input ...
salary_range_by_job_classification(biweekly_high_rate) as (
          SELECT '$0.00'
UNION ALL SELECT '$15.00'
UNION ALL SELECT '$25.00'
UNION ALL SELECT '$50.00'
UNION ALL SELECT '$100.00'
UNION ALL SELECT '$100.00'
UNION ALL SELECT '$200.00'
UNION ALL SELECT '$500.00'
UNION ALL SELECT '$0.00'
UNION ALL SELECT '$10630.00'
UNION ALL SELECT '$9175.00'
UNION ALL SELECT '$4142.00'
UNION ALL SELECT '$5242.00'
UNION ALL SELECT '$3293.00'
UNION ALL SELECT '$4496.00'
UNION ALL SELECT '$4676.00'
UNION ALL SELECT '$4762.00'
UNION ALL SELECT '$11255.00'
UNION ALL SELECT '$10376.00'
UNION ALL SELECT '$9096.00'
UNION ALL SELECT '$9456.00'
UNION ALL SELECT '$9641.00'
UNION ALL SELECT '$7392.00'
UNION ALL SELECT '$7687.00'
UNION ALL SELECT '$7835.00'
)
SELECT
  -- the first character is the dollar sign. 
  -- the rest is a numeric literal. Cast that as a DECIMAL(9,2).
  -- so start from the second character of the string, using SUBSTR().
  -- then use the same cast and filter out zeroes.
  MIN(CAST(SUBSTR(biweekly_high_rate,2) AS DECIMAL(9,2))) AS minrate
FROM salary_range_by_job_classification
WHERE CAST(SUBSTR(biweekly_high_rate,2) AS DECIMAL(9,2)) > 0
;
-- out  minrate 
-- out ---------
-- out    15.00
  

Ответ №4:

Использовать

     Select * from table where 
    Biweekly_high_Rate not like '$0.0%'
    order by 
   substr(2,Biweekly_high_Rate, 
    length(Biweekly_high_Rate)) 
     Limit 1
  

Ответ №5:

Вы можете преобразовать числовую часть значения в число, просто добавив 0 , используйте MIN() , чтобы получить его минимум, и используйте функцию printf() для его переформатирования:

 select printf('$%.2f', min(substr(Biweekly_High_Rate, 2)   0)) min_rate
from salary_range_by_job_classification
where Biweekly_High_Rate <> '$0.00'
  

Или с FIRST_VALUE() помощью функции window:

 select distinct first_value(Biweekly_High_Rate) over (order by substr(Biweekly_High_Rate, 2)   0) min_rate
from salary_range_by_job_classification
where Biweekly_High_Rate <> '$0.00'
  

Или отсортируйте по числовой части и получите 1-ю строку:

 select Biweekly_High_Rate min_rate
from salary_range_by_job_classification
where Biweekly_High_Rate <> '$0.00' 
order by substr(Biweekly_High_Rate, 2)   0 limit 1 
  

Посмотрите демонстрацию.
Результаты:

 > | min_rate |
> | :------- |
> | $15.00   |