Используйте только месяц в дате для запроса - PullRequest
0 голосов
/ 18 октября 2019

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

Как получить дату:

<Calendar x:Name="selectionMois" DisplayMode="Year" SelectionMode="SingleDate" 
    DisplayModeChanged="selectionMois_DisplayModeChanged"
    HorizontalAlignment="Left" Margin="0,55,0,0" VerticalAlignment="Top" 
    AllowDrop="True" Height="185" Width="226">

И

private void selectionMois_DisplayModeChanged( object sender, CalendarModeChangedEventArgs e )
{
    selectionMois.DisplayMode = CalendarMode.Year;
    this.dtMois = selectionMois.DisplayDate;
    LabelMois_Refresh();

    if( listAgentsCoches != null )
    {
        if( listAgentsCoches.Count > 0 ) BtImprimer.IsEnabled = true;
        else BtImprimer.IsEnabled = false;
    }
    else BtImprimer.IsEnabled = false;
}

this.dtMonth содержит дату в формате "YYYYY\MM\01".

Теперь у меня есть запрос или я хочу выбрать агентов, у которых есть контракт (контракт) в выбранном месяце.

Я хотел бы сделать что-то вроде:

StSQL ="SELECT DISTINCT Agent_Etablissement.Matricule, Nom, Prénom FROM Agent_Etablissement, Agents, contrats
        INNER JOIN CONTRATS ON Contrats.Matricule = Agents.Matricule AND  Contrats.IDEtablissement=Agent_Etablissement.IDEtablissement
        WHERE a contract exists for the chosen month

Таблица «Контрасты» содержит дату начала и дату окончания (эта может быть нулевой).

Как выбрать только те контракты, которые существуют в выбранном месяце?

Редактировать: база данных сервера SQL

database

Ответы [ 2 ]

1 голос
/ 18 октября 2019

например, если я выберу октябрь, все контракты, которые существуют в октябре: независимо от того, истекает ли они в декабре или заканчивается 15 октября.

переводится как

SELECT * FROM CONTRACTS
WHERE 
      ([DateDebut] >= '20191001' AND [DateDebut] <= EOMONTH('20191001')) -- starting in Oct
   OR ([DateFin] >= '20191001'   AND [DateFin] <= EOMONTH('20191001')) -- ending in Oct
   OR ([DateDebut] < '20191001'  AND ([DateFin] > EOMONTH('20191001') OR [DateFin] IS null)) -- started before Oct, but not ended

Пример

create table contracts ( [Id] varchar(3), [DateDebut] Date , [DateFin] Date, [Name] varchar(50) );
insert into contracts (id, [DateDebut], [DateFin], [Name]) values 
('1', '20120618', '20190920','[-] Before Oct'),
('2', '20190915', '20191015','[+] Ends middle of Oct'), 
('3', '20191020', '20191021','[+] Fully in Oct'),
('4', '20191028', '20191224','[+] Ends after Oct'),
('5', '20191128', '20191224','[-] After Oct'),
('6', '20190901', '20191001','[+] Ends 1st of Oct'),
('7', '20191001', '20191201','[+] Starts 1st of Oct'),
('8', '20191001', '20191031','[+] Full month'),
('9', '20191031', '20191201','[+] Starts 31st of Oct'),
('10', '20190901', '20191201','[+] Starts before Oct and ends after Oct');


SELECT * FROM CONTRACTS
WHERE 
--NOT(
      ([DateDebut] >= '20191001' AND [DateDebut] <= EOMONTH('20191001')) -- starting in Oct
   OR ([DateFin] >= '20191001'   AND [DateFin] <= EOMONTH('20191001')) -- ending in Oct
   OR ([DateDebut] < '20191001'  AND ([DateFin] > EOMONTH('20191001') OR [DateFin] IS null)) -- started before Oct, but not ended
--)

возвращает

Id  DateDebut   DateFin     Name
2   2019-09-15  2019-10-15  [+] Ends middle of Oct
3   2019-10-20  2019-10-21  [+] Fully in Oct
4   2019-10-28  2019-12-24  [+] Ends after Oct
6   2019-09-01  2019-10-01  [+] Ends 1st of Oct
7   2019-10-01  2019-12-01  [+] Starts 1st of Oct
8   2019-10-01  2019-10-31  [+] Full month
9   2019-10-31  2019-12-01  [+] Starts 31st of Oct
10  2019-09-01  2019-12-01  [+] Strats before Oct and ends after Oct

Просто чтобы быть уверенным, что НЕ (...) возвращает

Id  DateDebut   DateFin     Name
1   2012-06-18  2019-09-20  [-] Before Oct
5   2019-11-28  2019-12-24  [-] After Oct

Fiddle

Примечание: я использую '20191001', а не '2019-10-01', чтобы избежать сценария, в котором это означает 10 января вместо 1 октября.

0 голосов
/ 18 октября 2019

Вы можете использовать MONTH(), чтобы выбрать значение месяца из Datetime. Ниже должно работать, выбирая любой Контракт, где выбранная дата (месяц) больше чем Начальная и меньше чем Конечная дата (если это не нуль).

SELECT DISTINCT Agent_Etablissement.Matricule, Nom, Prénom 
FROM Agent_Etablissement, Agents, contrats
INNER JOIN CONTRATS ON Contrats.Matricule = Agents.Matricule AND  Contrats.IDEtablissement=Agent_Etablissement.IDEtablissement
WHERE (MONTH(@myDate) BETWEEN MONTH(StartDate) AND MONTH(EndDate)) 
   OR (MONTH(StartDate) >= MONTH(@myDate) AND EndDate IS NULL )

Примечание. Этот год не учитывается, поэтому будут возвращены все контракты, охватывающие октябрь (если был выбран октябрь).


Ниже также рассматривается год:

WHERE (MONTH(@myDate) BETWEEN MONTH(StartDate) AND MONTH(EndDate) 
   OR (MONTH(StartDate) >= MONTH(@myDate) AND EndDate IS NULL)) 

  AND (YEAR(@myDate) BETWEEN YEAR(StartDate) AND YEAR(EndDate) 
   OR (YEAR(StartDate) >= YEAR(@myDate) AND EndDate IS NULL))

Обратите внимание : этот ответ не является надежным при использовании более длинного диапазона дат (например, если [DateDebut] и [DateFin] охватывают начало / конец года, этозапрос не удастся). Вы можете добавить в запрос больше условий для обработки случаев, когда month(DateDebut) больше, чем month(DateFin) (т. Е. Даты охватывают начало / конец года).

Однако лучше применить фильтр DateDebut и DateFin с использованием операторов >=, <= или BETWEEN для фильтрации дат, как показано в других ответах.

Например:

WHERE [DateDebut] >= @monthStart
 AND ([DateFin] <= @monthEnd OR [DateFin] IS NULL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...