如何列出特定时间段内该月没有任何订单的所有月份

时间:2018-11-15 05:28:35

标签: sql sql-server

我想知道如何列出没有特定顺序的特定时间的所有月份。如果您能帮助我。

我的订单表中有OrderDate列

我就是这样:

select distinct month(Order.OrderDate) from Order where year(Order.OrderDate) = 1997

结果将显示仅在特定年份有订单的月份

我应该怎么做才能完成此查询

4 个答案:

答案 0 :(得分:0)

您正在寻找LEFT JOIN

CREATE TABLE Orders
(
  OrderDate DATE
);

INSERT INTO Orders VALUES
('2018-01-01'),
('2018-03-01'),
('2018-05-15');

DECLARE @MND DATE = (SELECT MIN(OrderDate) FROM Orders);
DECLARE @MXD DATE = (SELECT MAX(OrderDate) FROM Orders);

WITH CTE AS
(
  SELECT @MND OrderDate
  UNION ALL
  SELECT DATEADD(Month, 1, CTE.OrderDate)
  FROM CTE
  WHERE CTE.OrderDate <= DATEADD(Month, -1, @MXD)
)

SELECT MONTH(CTE.OrderDate) [Months]
FROM CTE LEFT JOIN Orders O ON MONTH(CTE.OrderDate) = MONTH(O.OrderDate)
                            AND
                              YEAR(CTE.OrderDate) = YEAR(O.OrderDate)
WHERE O.OrderDate IS NULL;
-- Add extra conditions here to filter the period needed

返回:

+--------+
| Months |
+--------+
|      2 |
|      4 |
+--------+

Demo

答案 1 :(得分:0)

您需要检索可以在下面的查询中使用的未下订单的月份

 ;WITH months(MonthNumber) AS
 (
    SELECT 1
    UNION ALL
    SELECT MonthNumber+1 
    FROM months
    WHERE MonthNumber < 12
 )
 SELECT DATENAME( month , DATEADD( month ,MonthNumber , 0 )  )
 FROM months
 EXCEPT
 SELECT DISTINCT month([Order].OrderDate) 
 FROM [Order] 
 WHERE YEAR([Order].OrderDate) = 1997

答案 2 :(得分:0)

您可以尝试使用如下所示的左联接

DEMO

select * from  
(
  VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
) AS M(val)
left join t1 on month(OrderDate)=val
and year(orderdate)=1997
where month(OrderDate) is null

答案 3 :(得分:0)

这里的问题是,如果我们有一个日期范围,那么我们可能会超出单个年份,例如,2017年7月1日至2018年6月30日有2年,因此创建一个月范围可能不适用于这种情况。可能的解决方案是在范围内列出所有月份以及年份,以便在搜索订单时按月份和年份进行搜索。

-- this is test order table, just to test the output
declare @order table(OrderDate date);
insert into @order(OrderDate) values('2018-01-01')

declare @dateRange table(d datetime not null primary key);

-- date range input parameter
declare @startDate date = '2017-06-01';
declare @endDate date = '2018-06-30';


-- modifying date range so that we go from start
-- of the month to the end of the month in the range
set @startDate = cast(year(@startDate) as varchar(100)) + '-' + cast(month(@startDate) as varchar(100)) + '-1';
set @endDate = dateadd(day, -1, dateadd(month, 1, cast(year(@endDate) as varchar(100)) + '-' + cast(month(@endDate) as varchar(100)) + '-1'));

-- creating dates for every month
declare @d date = @startDate;
while(@d <= @endDate)
begin
    insert into @dateRange(d) values(@d);
    set @d = dateadd(month, 1, @d);
end

-- selecting all the months in the range where
-- order does not exists
select  cast(year(t.d) as varchar(100)) + '-' + DATENAME(month, t.d) as [Month]
from    @dateRange as t
where   not exists(
            select  1 
            from    @order as x 
            where   month(x.OrderDate) = month(t.d) and year(x.OrderDate) = year(t.d)
        )
order by t.d

输出:(请注意,由于有订单,结果中缺少2018年1月)

Month
------------------
2017-June
2017-July
2017-August
2017-September
2017-October
2017-November
2017-December
2018-February
2018-March
2018-April
2018-May
2018-June