简体   繁体   English

仅使用日期中的月份进行查询

[英]Use only the month in a date for a query

I'm looking for a way to manipulate the month in a request, which I get from a date.我正在寻找一种在请求中操纵月份的方法,该请求是从日期中获得的。 (It's not MVVM) (这不是 MVVM)

How i get the date:我如何得到日期:

<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">

And

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 contains the date in "YYYYY\MM\01" format. this.dtMonth包含"YYYYY\MM\01"格式的日期。

Now I have a query or want to select agents who have a contract (contrat) in the chosen month.现在我有一个查询或想要 select 在所选月份有合同(合同)的代理商。

I would like to do something like:我想做类似的事情:

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

"Contrats" Table contain starting date & ending date (this one can be null). “合同”表包含开始日期和结束日期(这个可以为空)。

How can I select only those contracts that exist in the selected month?我怎样才能 select 仅在所选月份存在的那些合同?

Edit: SQL server database编辑:SQL 服务器数据库

数据库

for example if I choose October, all contracts that exist in October: no matter if they end in December, or if they end on October 15.例如,如果我选择 10 月,则所有存在于 10 月的合同:无论它们是在 12 月结束,还是在 10 月 15 日结束。

translates to翻译成

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

Example例子

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
--)

returns返回

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

Just to be sure WERE NOT (...) returns只是为了确保没有(...)返回

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

Fiddle小提琴

Note: I use '20191001' and not '2019-10-01' to avoid a scenario where it means the 10th of January, instead of 1st of October.注意:我使用“20191001”而不是“2019-10-01”来避免表示 1 月 10 日而不是 10 月 1 日的情况。

It is a little tricky.这有点棘手。 You need to select the rows whose dates intersect the [2019-10-01, 2019-10-31] range.您需要 select 日期与[2019-10-01, 2019-10-31]范围相交的行。 You can do so like this:你可以这样做:

WHERE  '2019-10-31' >= [Date Debut]
  AND ('2019-10-01' <= [Date Fin] OR [Date Fin] IS NULL)

Here is a demo on db<>fiddle showing all test cases.这是一个关于 db<>fiddle 的演示,显示了所有测试用例。

Note that I have assumed that end date is inclusive eg the end date 2019-10-01 must be included in October 2019 searches.请注意,我假设结束日期包括在内,例如结束日期2019-10-01必须包含在 2019 年 10 月的搜索中。

You can use MONTH() to select the month value from a Datetime.您可以使用MONTH()到 select 日期时间的月份值。 The below should work, selecting any Contract where the selected date (month) is greater than the Start and less than End date (if it's not null).下面应该起作用,选择所选日期(月份)大于开始日期且小于结束日期(如果它不为空)的任何合同。

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 )

Note: This doesn't consider the year, so would return all contracts that spanned October (if October was selected).注意:这不考虑年份,因此将返回跨越 10 月的所有合同(如果选择了 10 月)。


The below also considers the year:以下还考虑了年份:

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))

Please note : this answer is not robust when using a longer date range (for example, if [DateDebut] and [DateFin] span the beginning/end of a year this query will fail).请注意:当使用较长的日期范围时,此答案并不可靠(例如,如果[DateDebut][DateFin]跨越一年的开始/结束,则此查询将失败)。 You could add more conditions to the query to handle cases when month(DateDebut) is greater than month(DateFin) (ie the dates span the beginning/end of a year).month(DateDebut)大于month(DateFin) (即日期跨越一年的开始/结束)时,您可以向查询添加更多条件以处理情况。

However, a better approach is to filter DateDebut and DateFin using >= , <= operators or BETWEEN to filter the dates as shown in other answers.但是,更好的方法是使用>=<=运算符或BETWEEN过滤DateDebutDateFin以过滤日期,如其他答案所示。

For example:例如:

WHERE [DateDebut] >= @monthStart
 AND ([DateFin] <= @monthEnd OR [DateFin] IS NULL)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM