Можно ли избавиться от повтора заменив на WHERE rn<30 или типа того?

167
27 июня 2018, 11:30
SELECT 
    DAYOFYEAR(`birthday`) - DAYOFYEAR(CURDATE()) + CASE
        WHEN DAYOFYEAR(`birthday`) < DAYOFYEAR(CURDATE()) THEN 365
        ELSE 0
    END AS rn, users.*
FROM users 
WHERE (DAYOFYEAR(`birthday`) - DAYOFYEAR(CURDATE()) + CASE
        WHEN DAYOFYEAR(`birthday`) < DAYOFYEAR(CURDATE()) THEN 365
        ELSE 0
    END < 30)
ORDER BY rn
LIMIT 100;
Answer 1

Напишите детерминированную функцию от двух параметров

CREATE FUNCTION sf_date_diff(
  in_date1 DATE,
  in_date2 DATE
)
 RETURNS INTEGER
 DETERMINISTIC
BEGIN
  DECLARE var_day1 INTEGER;
  DECLARE var_day2 INTEGER;
  DECLARE var_res INTEGER;
  SET var_day1 = DAYOFYEAR(in_date1);
  SET var_day2 = DAYOFYEAR(in_date2);
  SET var_res = var_day1 - var_day2;
  IF (var_res < 0) THEN
    SET var_res = var_res + 365;
  END IF;
  RETURN var_res;
END;

И вызовите ее в запросе

SELECT
  sf_date_diff(`birthday`, CURDATE()) AS rn,
  users.*
FROM
  users 
WHERE
  sf_date_diff(`birthday`, CURDATE()) < 30
ORDER BY rn
LIMIT 100;

За счет детерминированности вызов функции будет происходить только для разных входных параметров

А еще можно через подзапросы

SELECT
  *
FROM
  (
    SELECT
      DAYOFYEAR(`birthday`) - DAYOFYEAR(CURDATE()) + CASE
        WHEN DAYOFYEAR(`birthday`) < DAYOFYEAR(CURDATE()) THEN 365
        ELSE 0
      END AS rn, users.*
    FROM users 
  ) sub
WHERE sub.rn < 30
ORDER BY sub.rn
LIMIT 100;
READ ALSO
помогите сопоставить SQL запрос

помогите сопоставить SQL запрос

помогите сопоставить SQL запрос

195
Правильный JOIN для выборки из двух таблиц

Правильный JOIN для выборки из двух таблиц

запутался я в джойнахПрошу помощи)) Короче, есть таблицы products и categories

162
Два header в одном файле

Два header в одном файле

Такая проблема, что 2 header

150