Я не так в DB, и у меня есть следующая проблема с этим запросом:
SELECT
count(*) AS exist
FROM Market_Commodity_Price_Series AS MCPS
INNER JOIN MarketDetails_CommodityDetails AS MD_CD
ON MCPS.market_commodity_details_id = MD_CD.id
INNER JOIN MarketDetails AS MD
ON MD_CD.market_details_id = MD.id
INNER JOIN CommodityDetails AS CD
ON MD_CD.commodity_details_id = CD.id
INNER JOIN CommodityName AS CN
ON CD.id = CN.commodity_details_id
WHERE
MD.market_name = "Butare"
AND CN.commodity_name = "Soya"
AND CN.language_id = 3
AND
MCPS.price_date >= DATE_FORMAT(STR_TO_DATE("03/15/2018", '%d/%m/%Y'), '%Y-%m-%d')
AND
MCPS.price_date <= DATE_FORMAT(STR_TO_DATE("03/15/2018", '%d/%m/%Y'), '%Y-%m-%d')
Проблема в том, что он всегда возвращает 0 в качестве вывода.
Я понял, что проблема связана с этими условиями ГДЕ:
AND
MCPS.price_date >= DATE_FORMAT(STR_TO_DATE("03/15/2018", '%d/%m/%Y'), '%Y-%m-%d')
AND
MCPS.price_date <= DATE_FORMAT(STR_TO_DATE("03/15/2018", '%d/%m/%Y'), '%Y-%m-%d')
проблема в том, что поле price_date моей таблицы Market_Commodity_Price_Series содержит значение 15/03/2018, а не 03/15/2018.
Этот запрос использует:
DATE_FORMAT(STR_TO_DATE("03/15/2018", '%d/%m/%Y'), '%Y-%m-%d')
для преобразования из формата даты в другой, но кажется, что он не работает.
Зачем? Что случилось? Что мне не хватает? Как я могу исправить эту проблему?
Второй аргумент STR_TO_DATE
- это формат, который должен соответствовать строке даты, в которую вы проходите.
'%d/%m/%Y'
означает, что месяц должен быть вторым, но поскольку в вашем случае не будет 15-го месяца, месяц должен быть первым, а затем днем.
DATE_FORMAT(STR_TO_DATE("03/15/2018", '%m/%d/%Y'), '%Y-%m-%d')
должно исправить это.
'%Y-%m-%d'
и данные столбца в %d/%m/%Y
Это трудно понять наверняка, так как вы не разместили свою схему таблиц, но, похоже, вы храните price_date
в виде строки и затем пытаетесь сравнить ее с датой. Сравнение строк таким образом может работать, но не всегда так, как вы ожидаете. Было бы предпочтительнее либо преобразовать обе даты в формат фактической date
, либо использовать временную метку unix:
STR_TO_DATE(MCPS.price_date,'%d/%m/%Y') >= STR_TO_DATE('03/15/2018','%m/%d/%Y')
или же
UNIX_TIMESTAMP(STR_TO_DATE(MCPS.price_date,'%d/%m/%Y')) >= UNIX_TIMESTAMP(STR_TO_DATE('03/15/2018','%m/%d/%Y'))
Обе из них должны работать, но проблема остается в том, что вы будете получать относительно низкую производительность таким образом и забыть об использовании какого-либо индекса.
Лучшим подходом было бы сохранить дату в формате date
для начала и рассмотреть возможность использования индекса для повышения эффективности.
Самый простой способ добиться того, что вы пытаетесь сделать, - просто использовать date_format для самого столбца. Я надеюсь, что значения столбца - формат DateTime.
так просто делай
DATE_FORMAT(MCPS.price_date,'%c-%d-%Y') >= STR_TO_DATE("03/15/2018", '%c-%d-%Y')
AND
DATE_FORMAT(MCPS.price_date,'%c-%d-%Y') <=(STR_TO_DATE("03/15/2018", '%c-%d-%Y')
>=
что может работать, но не всегда так, как вы ожидаете. Было бы лучше конвертировать обе даты в метку времени или использовать даты, указанные выше, для сравнения.