Не удается получить запрос LIKE, чтобы получить результаты записей за 2 и 4 цифры за год

0

У меня есть база данных mysql со столбцом "год", а значения, которые в настоящее время хранятся, составляют 2 и 4 цифры за каждый год, например "18" и "2018".

Я пытаюсь использовать LIKE для возврата записей как для 18, так и для 2018, где пользователь выбирает "2018" в год в форме html.

До сих пор, используя подход ниже, он возвращает только значения для 2018 года, а не значения, в которых данные года хранятся так же, как "18",

Я вижу, что он передает значение "2018", как следует в URL-адресе, и снова, он отлично подходит для возврата результатов, соответствующих 2018.

Вот полный запрос:

$year = $_GET['year'];

$query = "(
SELECT * 
FROM test
WHERE ('$name' IS NULL OR '$name' = '' OR name = '$name')
AND ('$city' IS NULL OR '$city' = '' OR city = '$city') AND ('$state' IS NULL 
OR '$state' = '' OR state = '$state') AND ('$county' IS NULL OR '$county' 
= '' OR county = '$county') AND ('$year' IS NULL OR '$year' = '' 
OR year LIKE '%$year%') AND ('$month' IS NULL OR '$month' = '' OR
month = '$month')order by name)";
  • 0
    Вы делаете что-то не так, это должно работать, см. Ibb.co/ghRdHc
  • 0
    @ Mr.Anonymous Ну, я не могу указать, что соответствует «18», как в вашем примере, потому что это динамическая переменная, которая вводится как год (в данном случае 2018). Может быть, он не может найти 18 шаблонов из 4 цифр, когда он как-то динамически передается?
Показать ещё 9 комментариев
Теги:

4 ответа

1
$year = 18;
select * from test where year LIKE '$year%'; //OUTPUTS YEAR STARTS WITH 18
select * from test where year LIKE '%$year'; //OUTPUTS YEAR ENDS WITH 18
select * from test where year LIKE '%$year%'; //OUTPUTS YEAR WITH PATTERN OF 18
  • 0
    Да, я тоже это нашел, но он все равно просто возвращает результаты 2018 года, когда я использую шаблон% $ year, который мне нужен. Я получаю значение $ year с другой страницы, используя GET, и это не проблема. Это работает для 2018, но все еще не дает результаты для 18
  • 0
    Мой запрос немного сложнее, чем я впервые поделился. Я редактировал вопрос, но я не думаю, что это имеет значение ..
Показать ещё 3 комментария
0

Ваши данные просто сломаны. Вы должны были нормализовать данные перед их сохранением в базе данных.

Подготовка к хранению

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

function normaliseYear(int $year): int
{
    if (999 < $year && $year < 10000) {
        // Year is already normalised
        return $year;
    }

    if (0 <= $year && $year < 100) {
        // Got the year within the century, assume 21. century
        return 2000 + $year;
    }

    // You can put other repairable cases here

    // Got something we can not repair
    throw new UnexpectedValueException("Unable to normalise $year as a year");
}

Вы используете эту функцию/метод как для создания и извлечения данных, поэтому ваша база данных чистая, а запросы остаются простыми (= быстро).

Восстановление Хранилища

Поскольку у вас уже есть "плохие" данные в вашей базе данных, вам необходимо их восстановить. На самом деле вам нужно сделать такую же нормализацию по существующим данным, но, к счастью, только один раз.

UPDATE test SET year = 2000 + year WHERE year < 100;

Запрос

Тогда ваш запрос будет выглядеть так:

$year = ($year === '' || $year === null) ? null : normaliseYear((int)$_GET['year']);

// Do not forget to sanitise user input!
$month = (int)$month;
// ...

$skipName   = empty($name) ? 1 : 0;
$skipCity   = empty($city) ? 1 : 0;
$skipState  = empty($state) ? 1 : 0;
$skipCounty = empty($county) ? 1 : 0;
$skipYear   = ($year === null) ? 1 : 0;
$skipMonth  = empty($month) ? 1 : 0;

$query = "(
    SELECT * 
    FROM test
    WHERE ($skipName OR name = '$name')
      AND ($skipCity OR city = '$city')
      AND ($skipState OR state = '$state')
      AND ($skipCounty OR county = '$county')
      AND ($skipYear OR year = $year)
      AND ($skipMonth OR month = $month)
    ORDER BY name
)";
0

Я нашел, что ваш пользователь выбирает 2018, и вы используете как на 2018 год только в том виде, в котором ваш код предлагает:

$ year = $ _GET ['year'];

Я предлагаю вам передать только 2 символа в переменную $ year, и все будет хорошо.

  • 0
    Лол. Я не уверен, что это дает правильный ответ, но это то, что я только что решил сделать. Я конвертирую все в 2 цифры, так как 4 все равно не требуется для моего сайта. Просто нужно немного почистить свидание
0

Вы можете "нормализовать" year с year % 100 + 2000. Поэтому, если вы ищете 2018, это условие будет

year % 100 + 2000 = 2018

Это будет соответствовать: year = 18 и year = 2018. Но и year = 118.

Обратите внимание, что NULL будет преобразован в пустую строку в PHP. Так что-то вроде '$name' IS NULL никогда не произойдет. И вы можете упростить свой запрос:

SELECT * 
FROM test
WHERE '$name'   IN ('', name)
  AND '$city'   IN ('', city)
  AND '$state'  IN ('', state)
  AND '$county' IN ('', county)
  AND '$year'   IN ('', year % 100 + 2000)
  AND '$month'  IN ('', month)
order by name

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню