MySQL заказать в этом запросе - PullRequest
0 голосов
/ 13 июня 2018

как я могу добавить "заказ по созданному asc" в этом запросе:

(select user.first_name as prenom, user.last_name as nom, fvll.created_on, fvll.bar_code, "R" from stk_fuel_voucher_line fvll,stk_fuel_voucher fv, adm_user user 
where YEAR(fvll.created_on)=? and MONTH(fvll.created_on) = ? and user.id=fv.id_user and fv.id=fvll.id_fuel_voucher and
fvll.bar_code not in 
(select fvl.bar_code
from stk_fuel_voucher_line fvl, stk_fuel_voucher_book fvb
where fvl.bar_code >= fvb.first_bar_code and fvl.bar_code <=fvb.last_bar_code
and YEAR(fvl.created_on)=? and MONTH(fvl.created_on) = ?))

UNION

(select user2.first_name as prenom, user2.last_name as nom, fvll2.created_on, fvll2.bar_code, "B"
from stk_fuel_voucher fv2, stk_fuel_voucher_book fvb2, stk_fuel_voucher_line fvll2, adm_user user2 
where fvll2.bar_code >= fvb2.first_bar_code and fvll2.bar_code <=fvb2.last_bar_code and user2.id=fv2.id_user and fv2.id=fvll2.id_fuel_voucher
and YEAR(fvll2.created_on)=? and MONTH(fvll2.created_on) = ?)

1 Ответ

0 голосов
/ 13 июня 2018

Мне кажется, что эти два запроса одинаковы, с той лишь разницей, что они определяют, есть ли соответствующий штрих-код, и возвращают 'B' или 'R' в зависимости.

Я бы избегал лишнихRigmarole о UNION и просто сделать один запрос с условным тестом, чтобы определить, возвращается ли 'B' или 'R'.

Если намерение оператора UNION (вместо более обычногоUNION ALL) - для удаления дубликатов из каждого набора, для этого можно использовать предложение GROUP BY или ключевое слово DISTINCT.(В исходном запросе мы гарантируем, что между этими двумя наборами не будет дубликатов, так как на множестве всегда указано «R», в другом наборе всегда есть буква «B».

Я неиметь представление о спецификации для запроса, но основываясь на том, что я могу выделить из существующего запроса, я бы вместо этого попытался сделать что-то вроде этого:

SELECT user.first_name    AS prenom
     , user.last_name     AS nom
     , fvll.created_on    AS created_on
     , fvll.bar_code
     , CASE WHEN ni.bar_code IS NULL THEN 'R' ELSE 'B' END AS r
  FROM stk_fuel_voucher_line fvll
  JOIN stk_fuel_voucher fv
    ON fv.id = fvll.id_fuel_voucher
  JOIN adm_user user
    ON user.id = fv.id_user
  LEFT
  JOIN ( SELECT fvl.bar_code
           FROM stk_fuel_voucher_line fvl
           JOIN stk_fuel_voucher_book fvb
             ON fvb.first_bar_code <= fvl.bar_code
            AND fvb.last_bar_code  >= fvl.bar_code
          WHERE YEAR(fvl.created_on)  = ?
            AND MONTH(fvl.created_on) = ?
          GROUP BY fvl.bar_code
       ) ni
    ON ni.bar_code = fvll.bar_code
  WHERE YEAR(fvll.created_on)  = ?
   AND MONTH(fvll.created_on) = ?

 GROUP
    BY user.first_name    AS prenom
     , user.last_name     AS nom
     , fvll.created_on
     , fvll.bar_code
     , CASE WHEN ni.bar_code IS NULL THEN 'R' ELSE 'B' END

 ORDER
    BY fv11.created_on

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

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

Вместо этого:

   WHERE YEAR(fvll.created_on)  = ?
     AND MONTH(fvll.created_on) = ?

Я бы написал что-то вроде

  WHERE fvll.created_on >=  month_begin_dt + INTERVAL 0 MONTH
    AND fvll.created_on >=  month_begin_dt + INTERVAL 1 MONTH

с month_begin_dt, представляющим выражение, которое возвращает первый день месяца, однакоэто должно быть передано, если нам нужно построить ДАТУ из года и месяца, мы могли бы сделать это. Конечная цель будет иметь эквивалент:

  WHERE fvll.created_on >=  '2018-05-01' + INTERVAL 0 MONTH
    AND fvll.created_on >=  '2018-05-01' + INTERVAL 1 MONTH
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...