查询以查找表中不可用的所有日期

时间:2012-07-25 19:59:14

标签: sql

我想为此问题编写一个查询:

  

显示1997年8月没有订单的日子。

我能够找到下订单的日子,但我怎样才能找到没有下订单的日子?

这显示了下订单的日期:

SELECT
   o.OrderID,
   day(o.OrderDate) AS 'Date',
   sup.CompanyName 
FROM
   Orders o 
   INNER JOIN OrderDetails od ON o.OrderID = od.OrderID 
   INNER JOIN Products p ON od.ProductID = p.ProductID 
   INNER JOIN Suppliers sup ON p.SupplierID = sup.SupplierID 
WHERE
   sup.CompanyName = 'Tokyo Traders'
   AND o.OrderDate BETWEEN '1/1/1997' AND '1/31/1997'

3 个答案:

答案 0 :(得分:2)

您需要一个可以加入的日期表来查找缺少的日期。

假设它的SQL Server:

您可以加入查询,以获取结果

WITH DatesTable
AS
(
  SELECT CAST('2007-08-01' as datetime) AS [date]
  UNION ALL
  SELECT DATEADD(dd, 1, [date])
  FROM DatesTable
  WHERE DATEADD(dd, 1, [date]) <= '2007-08-31'
)
SELECT [date] FROM DatesTable
OPTION (MAXRECURSION 0);

有些类似于

的东西
WITH DatesTable
AS
(
  SELECT CAST('2007-08-01' as datetime) AS [date]
  UNION ALL
  SELECT DATEADD(dd, 1, [date])
  FROM DatesTable
  WHERE DATEADD(dd, 1, [date]) <= '2007-08-31'
)
SELECT DT.[date]
FROM
   DatesTable DT 
   Left Outer Join Orders o on o.OrderDate = DT.[Date]

WHERE o.OrderDate is null

OPTION (MAXRECURSION 0);

答案 1 :(得分:0)

跨数据库执行此操作的方法是创建一个包含每个日期行的表,然后将其连接到详细信息表;空值是没有匹配的地方。

答案 2 :(得分:0)

假设SQL Server:

WITH Dts AS (
   SELECT DateAdd(day, V.number, '19970801') Dt
   FROM master.dbo.spt_values V
   WHERE V.type = 'P'
   AND V BETWEEN 1 AND 31
)
SELECT Dts.Dt
WHERE NOT EXISTS (
   SELECT *
   FROM
      Orders o 
      INNER JOIN Suppliers sup ON p.SupplierID = sup.SupplierID 
   WHERE
      sup.CompanyName = 'Tokyo Traders'
      AND Dts.Dt = o.OrderDat
)

我在公司名称中保留了您的条件,因为我认为您希望Tokyo Traders没有下订单的日子。