SQL как предложение для дат - PullRequest
2 голосов
/ 02 апреля 2011

Я запрашиваю базу данных, чтобы получить все сообщения в блоге за определенный месяц определенного года.Дата хранится в базе данных как ГГГГ-ММ-ДД

Каков наилучший надежный способ получения сообщений только определенного дня и года?Я пробовал составлять цепочки как пункты, но я пришел к выводу, что они могут потерпеть неудачу, например, если бы я использовал выражение:

'SELECT * FROM entries WHERE date LIKE \''.$year.'%\' AND date LIKE \'%'.$month_no.'%\''

Это не получится, если номер месяцасодержится в последних 3 цифрах номера года.Должен ли я использовать регулярные выражения, и если да, может ли кто-нибудь предложить утверждение, которое я мог бы использовать?

Ответы [ 8 ]

4 голосов
/ 02 апреля 2011

Пожалуйста .. просто используйте фильтр даты.Это поможет производительности (используйте индекс)

$query = "SELECT *
FROM entries
WHERE date >= '" . $year . "-" . $month_no . "-01'
  AND date <  adddate('" . $year . "-" . $month_no . "-01', interval 1 month)";

Это было для MySQL.Для SQL Server используйте нечто подобное, но вместо этого используйте DATEADD

...
WHERE date >= '$year" . $month . "01'
  AND date <  DATEADD(month,1,'$year" . $month . "01'";

Причина добавления одного месяца состоит в том, что легче обрабатывать случай, когда месяц равен 12 (декабрь).

2 голосов
/ 02 апреля 2011

Я бы подумал, что следующее должно решить эту проблему:

'SELECT * FROM entries WHERE date LIKE \''.$year.'-'.$month_no.'-%\''

Однако вам необходимо убедиться, что длина $year составляет четыре цифры, а $month_no - две цифры с использованием любого языка сценариев и т. Д., В котором вы создаете запрос.

2 голосов
/ 02 апреля 2011

Я бы порекомендовал создать еще один столбец с датой и временем (или просто датой, если это возможно).В дальнейшем было бы намного проще.

Кроме того, вы можете привести его к типу даты и запросить его.

1 голос
/ 02 апреля 2011

Надежная защита, вероятно, будет конвертировать ваши строки в даты:

DECLARE @dateToFind datetime

SET @dateToFind = CONVERT(datetime, N'2011-04-02', 20)

SELECT * FROM [table] WHERE CONVERT(datetime, [datefield], 20) = @dateToFind

Или, если вам нужен диапазон:

DECLARE @startDate datetime, @endDate datetime

SELECT 
    @startDate = CONVERT(datetime, N'2011-04-01', 20), 
    @endDate = CONVERT(datetime, N'2011-04-30', 20) 

SELECT * FROM [table] WHERE CONVERT(datetime, [datefield], 20) BETWEEN @startDate AND @endDate

Или вы можете конвертировать дважды:

SELECT * FROM [table] WHERE YEAR(CONVERT(datetime, [datefield], 20)) = 2011 AND MONTH(CONVERT(datetime, [datefield], 20)) = 4

Число 20 в конверте соответствует вашему формату даты.

1 голос
/ 02 апреля 2011

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

Но при условии, что вы на самом деле используете столбец символов, вы можете легко решить его без REGEX с помощью функции substring() или substr():

'SELECT * FROM entries 
WHERE substr(date, 1, 7) =  '.$year.'-'.$month_no

NB. Извините, я не распознаю ваш диалект SQL, поэтому, возможно, у меня неправильный синтаксис.

1 голос
/ 02 апреля 2011

Ваши данные хранятся в виде строки в базе данных, а не в качестве объекта даты? Посмотрите на создание объекта даты из строки, если это возможно, используя to_date или CAST. Существует множество функций даты и времени, которые делают это тривиальным для объекта даты, например, DATEPART в T-SQL и PL-SQL или YEAR, MONTH в MySql

1 голос
/ 02 апреля 2011

Я столкнулся с этим, когда создал базу данных о наблюдаемых событиях (мое было осложнено тем, что с точки зрения того, что я делал, мои дни фактически начинались с 8 утра, поэтому 01.02.2011 07:59: 59 "на самом деле считается за 1 января! Вы можете сделать несколько вещей

Вы были после определенного дня. Вы не упомянули, с какого языка вы вызываете SQL, так что ...

  1. Сохраните дату в виде даты с указанием времени, а затем используйте команду convert для преобразования ее в просто дату, которую вы можете запросить как обычно (см. «Преобразования для бесед»)

  2. Хранить в датах, как указано выше, и использовать между ними, поэтому $ date1 = 01.01.2011 00:00:00 и $ date2 = 02.01.2011 00:00:00 будут

    'select * from entries where date between "'.$date1.'" and "'.$date2.'"'
    
  3. придерживайтесь того, что у вас есть, и делайте

    'select * from entries where date = "'.$year.'/'.$month.'/'.$day.'"'
    

, но, по крайней мере, с полной датой и временем вы все равно можете заказать их в порядке времени.1021 *

1 голос
/ 02 апреля 2011

если поле DATE имеет тип DATE TYPE, тогда оператор «like» не работает, вы должны преобразовать тип даты в тип varchar, тогда вы можете использовать оператор «like» в результате преобразования.

Bye

...