Оператор Where для нахождения всех записей в определенном месяце

Исправлено с этим.

[value]="'00000000-0000-0000-0000-000000000000'"

Так что теперь это строка.

67
задан Tarks 12 May 2009 в 05:15
поделиться

8 ответов

Я думаю, что вам нужна функция MONTH (date) . Возможно, вы захотите также использовать 'YEAR' .

Предположим, у вас есть таблица с именем things , которая выглядит примерно так:

id happend_at
-- ----------------
1  2009-01-01 12:08
2  2009-02-01 12:00
3  2009-01-12 09:40
4  2009-01-29 17:55

Допустим, вы хотите выполнить, чтобы найти все записи, у которых есть could_at в течение месяца 2009/01 (январь 2009 г.). Запрос SQL будет выглядеть так:

SELECT id FROM things 
   WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009

Что вернет:

id
---
1
3
4
156
ответ дан 24 November 2019 в 14:29
поделиться

В качестве альтернативы функциям MONTH и YEAR также будет работать обычное предложение WHERE:

select *
from yourtable
where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'
2
ответ дан 24 November 2019 в 14:29
поделиться

Если вы используете SQL Server, загляните в DATEPART.

http://msdn.microsoft.com/en-us/library/ms174420 (SQL.90) .aspx

DATEPART (мм, [ДАТА, НА КОТОРУЮ ВЫ СМОТРИТЕ])

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

2
ответ дан 24 November 2019 в 14:29
поделиться

Использование функций МЕСЯЦ и ГОД, как предлагается в большинстве ответов, имеет тот недостаток, что SQL Server не сможет использовать какой-либо индекс, который может быть в вашем столбце даты. Это может снизить производительность большой таблицы.

Я был бы склонен передать значение DATETIME (например, @StartDate) в хранимую процедуру, которая представляет первый день интересующего вас месяца.

Затем вы можете использовать

SELECT ... FROM ...
WHERE DateColumn >= @StartDate 
AND DateColumn < DATEADD(month, 1, @StartDate)

Если вы должны передать месяц и год как отдельные параметры в хранимую процедуру, вы можете сгенерировать DATETIME, представляющую первый день месяца, с помощью CAST и CONVERT, а затем действуйте, как описано выше. Если вы сделаете это, я бы порекомендовал написать функцию, которая генерирует DATETIME из целых значений года, месяца, дня, например, из блога SQL Server .

create function Date(@Year int, @Month int, @Day int)
returns datetime
as
    begin
    return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
    end
go

Затем запрос выглядит следующим образом:

SELECT ... FROM ...
WHERE DateColumn >= Date(@Year,@Month,1)
AND DateColumn < DATEADD(month, 1, Date(@Year,@Month,1))
12
ответ дан 24 November 2019 в 14:29
поделиться

Могу я просто попросить сравнить по году и месяцу?

Можно. Вот простой пример использования образца базы данных AdventureWorks ...

DECLARE @Year       INT
DECLARE @Month      INT

SET @Year = 2002
SET @Month = 6

SELECT 
    [pch].* 
FROM 
    [Production].[ProductCostHistory]   pch
WHERE
    YEAR([pch].[ModifiedDate]) = @Year
AND MONTH([pch].[ModifiedDate]) = @Month
1
ответ дан 24 November 2019 в 14:29
поделиться

Что-то вроде этого должно сработать:

select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year

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

Iain

0
ответ дан 24 November 2019 в 14:29
поделиться

Я не уверен, что это ошибка в g ++ (начиная с версии 4.2.4). Теперь код переходит в g ​​++ 4.4 (см. ОБНОВЛЕНИЕ ниже). Чтобы этот код компилировался для других версий компиляторов, вы можете добавить набор скобок вокруг аргумента по умолчанию:

template<typename A, typename B>
class Foo { };

struct Bar {
  void method ( Foo<int,int> const& stuff = ( Foo<int,int>() ) );
};

ИМО, эти круглые скобки необходимы, поскольку существует дополнительное требование, чтобы аргумент по умолчанию мог ссылаться на член class, который может быть объявлен позже в теле класса:

struct Bar {
  void method ( int i = j);  // 'j' not declared yet
  static const int j = 0;
};

Приведенный выше код является допустимым, и когда объявление для 'метода' анализируется, член 'j' еще не был замечен. Поэтому компилятор может анализировать аргумент по умолчанию только с использованием синтаксиса и только проверки (т. Е. Сопоставления скобок и запятых). Когда g ++ анализирует ваше исходное объявление, на самом деле он видит следующее:

void method ( Foo<int,int> const& stuff = Foo<int // Arg 1 with dflt.
              , int>() );                         // Arg 2 - syntax error

Добавление дополнительных скобок гарантирует правильную обработку аргумента по умолчанию.

В следующем случае показан пример, в котором g ++ успешно выполняется, но Comeau по-прежнему генерирует синтаксическую ошибку:

template<int J, int K>
class Foo { };

struct Bar {
  void method ( Foo<0, 0> const & i = ( Foo<j, k> () ) );
  static const int j = 0;
  static const int k = 0;
};

EDIT:

В ответ на комментарий: «Вы могли бы также иметь здесь вызов функции с несколькими аргументами», Причина, по которой это не вызывает проблемы, заключается в том, что запятые внутри вызова функции заключены в круглые скобки:

int foo (int, int, int);
struct Bar {
  void method ( int j =
                    foo (0, 0, 0) ); // Comma's here are inside ( )
};

Следовательно, можно проанализировать это, используя только синтаксис выражения. В C ++ все символы '(' должны совпадать с ')', поэтому их легко проанализировать. Причина проблемы здесь в том, что «<» не нужно сопоставлять, поскольку он перегружен в C ++ и поэтому может быть оператором «меньше» или началом списка аргументов шаблона. В следующем примере показано, где «<» используется в аргументе по умолчанию и подразумевает оператор «меньше чем»:

template<int I, int J>
class Foo { };

struct Bar {
  template <typename T> struct Y { };

  void method ( ::Foo<0,0> const& stuff = Foo<10 , Y < int >  = Y<int>() );

  struct X {
    ::Foo<0, 0> operator< (int);
  };

  static X Foo;
};

Вышеупомянутое «Foo <10» - это вызов «operator <», определенный в 'X', а не начало список аргументов шаблона. Опять же, Comeau генерирует синтаксические ошибки в приведенном выше коде, и g ++ (включая 3.2.3) анализирует это правильно.

FYI, соответствующие ссылки - это примечание в 8.3.6 / 5:

[Примечание: в объявлениях функций-членов просматриваются имена в выражениях аргументов по умолчанию вверх, как описано в 3.4.1 ...

, а затем в 3.4.1 / 8

Имя, используемое в определении функции-члена (9.3) класса X после declaratorid29 функции) должен быть объявлен одним из следующих способов:

...

- должен быть членом класса X или быть членом базового класса X (10.2), или

Этот пункт здесь является часть, которая заставляет компилятор «откладывать» поиск значения аргумента по умолчанию до тех пор, пока не будут объявлены все члены класса.

Как указано в «Занятом русском языке», g ++ 4.4 теперь способен разобрать все эти примеры. Однако до тех пор, пока DR не будет рассмотрен комитетом по стандартам C ++, я еще не готов называть это «ошибкой». Я считаю, что для обеспечения переносимости на другие компиляторы / инструменты (и, возможно, даже в будущие версии g ++) потребуются дополнительные круглые скобки.

По моему опыту, стандарт C ++ не требует, чтобы все поставщики компиляторов использовали одну и ту же технологию синтаксического анализатора, и они также не могут ожидать, что все технологии будут одинаково мощными. В результате требования к синтаксическому анализу обычно не требуют, чтобы поставщики совершали сверхчеловеческие подвиги. Чтобы проиллюстрировать это, рассмотрим следующие два примера:

typedef T::TYPE TYPE;
T::TYPE t;

Если 'T' является зависимым, то для каждого контекста 'TYPE' должен быть именем типа, однако стандарт по-прежнему требует имени типа ключевое слово. Эти примеры однозначны и могут означать только одно, однако стандарт (чтобы разрешить все технологии синтаксического анализа) по-прежнему требует ключевого слова typename .

It» это находит пару даты начала и даты окончания для текущего месяца, просто замените CURRENT_TIMESTAMP на параметр типа DATETIME (обратите внимание, что значение 1990-01-01 совершенно произвольно):

SELECT DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-01T00:00:00.000'), 
       DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-31T23:59:59.997')
1
ответ дан 24 November 2019 в 14:29
поделиться

Одним из способов было бы создать переменную, которая представляет первое число месяца (т.е. 5/1/2009), либо передать ее в процесс, либо построить (объединить месяц / 1 / год ). Затем используйте функцию DateDiff.

WHERE DateDiff(m,@Date,DateField) = 0

Она вернет все, что имеет соответствующий месяц и год.

0
ответ дан 24 November 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: