【问题标题】:MS Access SQL Query to report daily figures for the whole year even when no sales made on a particular dayMS Access SQL 查询报告全年的每日数据,即使在特定日期没有销售
【发布时间】:2019-07-02 17:11:29
【问题描述】:

我被要求生成一个数据表/可导出的输出到 Excel,显示来自活动预订的每日总收入。

如果您将顶部的日期想象为列标题,将“事件子类型”(即婚礼、会议、研讨会等)作为行,其中每个事件子类型的收入的财务价值相加并显示在相应的列中'日期事件开始'。

我已经编写了一个交叉表报告,该报告按月汇总。该报告的代码如下所示并且工作正常,但我的财务人员希望查看一年中每一天的每日数据,包括数据库中实际不存在数据的每一天的“0”。我似乎不能:

  • 创建代码以按天显示结果(我使用下面粘贴的代码 作为起点)
  • 获取要加入的日期表,以便我可以 显示所有日期,包括没有事件的日期。

我的数据库有以下表格:

Dates (ID, Dates = DateTime values from 1/1/2017 - 31/12/2117)

Enquiries (ID, [Customer ID], [Event Name],[Main Status],[Date Event Start],[Event Sub Category])

Financials (ID, [Enquiry ID], [Estimated Income], [Actual Income])

Customers (ID, [CustName] etc)

Sql 查询:

SELECT enquiries.[event name], 
       enquiries.[main status], 
       enquiries.[date event start], 
       enquiries.[event sub category], 
       financials.[actualincome], 
       financials.[estimatedincome], 
       enquiries.id, 
       Year([date event start])            AS [Year], 
       Month([date event start])           AS [Month], 
       Datepart("q", [date event start])   AS Quarter, 
       Format([date event start], "mmmm")  AS [Month Name], 
       ( Month([date event start]) MOD 3 ) AS MonthOfQuarter, 
       Switch(enquiries.[main status] = 'PIPELINE ENQUIRY' 
               OR enquiries.[main status] = 'Booking Form Sent', 
       financials.[estimatedincome])       AS EstimatedPipelineIncome, 
       Switch(enquiries.[main status] = 'CONFIRMED BOOKING' 
               OR enquiries.[main status] = 'Ts & Cs and Quote Sent' 
               OR enquiries.[main status] = 'Signed Ts & Cs Received', 
       financials.[actualincome])          AS ConfirmedIncome, 
       Switch(enquiries.[main status] = 'EVENT COMPLETED', 
       financials.[actualincome]) 
                                           AS CompletedIncome 
FROM   customers 
       INNER JOIN (enquiries 
                   INNER JOIN financials 
                           ON enquiries.id = financials.[enquiry id]) 
               ON customers.id = enquiries.[customer id] 
WHERE  (( ( enquiries.[main status] ) = "pipeline enquiry" 
           OR ( enquiries.[main status] ) = "booking form sent" 
           OR ( enquiries.[main status] ) = "confirmed booking" 
           OR ( enquiries.[main status] ) = "ts & cs and quote sent" 
           OR ( enquiries.[main status] ) = "signed ts & cs received" 
           OR ( enquiries.[main status] ) = "event completed" )) 
ORDER  BY enquiries.[date event start];  

我已经在 SO 上查看了 3 周的类似问题和答案 - 但我似乎无法让这些问题与我自己的实例一起使用,因为我遇到了 SQL 问题。

是否有人能够帮助提供 SQL 代码,帮助我将 Dates 表适当地添加到此 SQL 中,并修改查询以解决此问题?

这是我的第一篇文章,所以请指出我需要在哪里提供更多信息或以不同的方式提出帮助!

更新

以下代码用于拉回完整的日期列表,事件在它们存在的位置正确对齐,但不包括加入财务表以添加相应货币值的代码,因为我似乎无法正确嵌套连接:

SELECT Dates.Dates, Enquiries.[Event Sub Category], Financials.ActualIncome, Financials.[Total Booking Value Incl VAT]
FROM Dates LEFT JOIN Enquiries ON Dates.[Dates] = Enquiries.[Date Event Start];

因此我实际上需要以下工作,但无法做到:

SELECT Dates.Dates, Enquiries.[Event Sub Category], Financials.ActualIncome, Financials.[Total Booking Value Incl VAT]
FROM (Enquiries INNER JOIN Financials ON Enquiries.[ID] = Financials.[Enquiry ID]) LEFT JOIN Dates ON Dates.[Dates] = Enquiries.[Date Event Start];

【问题讨论】:

  • 我假设您想加入Enquiries.[Date Event Start] = Dates.SomeDate 上的两个表。如果我是对的,您必须使用您的查询 right join Dates 表。请阅读:Visual Representation of SQL Joins。这可能有助于您了解如何实现目标。
  • 我认为 Enquiries.[Date Event Start] = Dates.SomeDate 似乎是明智的 - 但这是我感到困惑的领域。作为参考,其他表当前连接为: Enquiries.ID = Financials.[EnquiriesID] 作为一对多;和 Customers.ID = Enquiries.[CustomersID] 一对多。

标签: sql ms-access left-join inner-join


【解决方案1】:

正如我在问题的评论中提到的,您已经使用left join 加入[Dates] 表(我之前错了),这使您能够从 [Dates] 表中获取所有日期以及从其他表中获取相应数据。请参考我在评论中提供的链接。

提示:使用table aliases。它使 SQL 代码更具可读性。

看看这个查询:

SELECT D.[EventDate], E.[Event Name], E.[MAIN STATUS], 
    E.[Event Sub Category], F.[ActualIncome], F.[EstimatedIncome],
    E.ID, Year(D.[EventDate]) AS [Year], Month(D.[EventDate]) AS [Month],
    DatePart("q",D.[EventDate]) AS Quarter, Format(D.[EventDate],"mmmm") AS [Month Name],
    (Month(D.[EventDate]) Mod 3) AS MonthOfQuarter,
    Switch(E.[MAIN STATUS]='PIPELINE ENQUIRY' Or E.[MAIN STATUS]='Booking Form Sent', F.[EstimatedIncome]) AS EstimatedPipelineIncome,
    Switch(E.[MAIN STATUS]='CONFIRMED BOOKING' Or E.[MAIN STATUS]='Ts & Cs and Quote Sent' Or E.[MAIN STATUS]='Signed Ts & Cs Received',F.[ActualIncome]) AS ConfirmedIncome,
    Switch(E.[MAIN STATUS]='EVENT COMPLETED',F.[ActualIncome]) AS CompletedIncome
FROM [Dates] D LEFT JOIN (
        Customers C INNER JOIN (
            Enquiries E INNER JOIN Financials F ON E.ID = F.[Enquiry ID])
                ON C.ID = E.[Customer ID])
            ON D.EventDate = E.[Date Event Start]
WHERE (((E.[MAIN STATUS])="PIPELINE ENQUIRY" Or 
    (E.[MAIN STATUS])="Booking Form Sent" Or 
    (E.[MAIN STATUS])="CONFIRMED BOOKING" Or 
    (E.[MAIN STATUS])="Ts & Cs and Quote Sent" 
    Or (E.[MAIN STATUS])="Signed Ts & Cs Received" 
    Or (E.[MAIN STATUS])="EVENT COMPLETED"))
ORDER BY E.[Date Event Start];

请注意,我无权访问您的数据,因此上述 sql 代码可能包含错误。

【讨论】:

  • 我想我把你弄糊涂了,因为“日期”表只包含从 2017 年到 2017 年的每个日期的列表;它不包含事件日期,那些在查询中引用。[日期事件开始]。我尝试了您的代码,它返回了事件列表,但没有其他数据显示没有事件的日期。谢谢你,我也会看看你提供的链接。
  • @Jess,我称该字段为EventDate,因为您没有在 [Dates] 表中提供文件的名称。根据您的要求,您希望显示所有日期,因此,有些行带有日期但没有详细信息,请不要感到惊讶。这意味着 [Enquires] 表不包含基于 [Date Event Start](等于 [EventDate])的相应数据。继续仔细查看right join 声明并阅读推荐文章。干杯!马切伊
  • 啊,不,对不起,我的回复没有说清楚。道歉。我的意思是说我尝试了你的代码,它只像以前一样返回事件列表,但它没有返回任何没有我想要的数据的日期。 IE 查询的执行方式与我发布问题之前的方式相同。我肯定会看那篇文章,最终会到达那里!非常感谢!
  • 对不起,我错了,你必须使用left join。嗯,有时会发生这样的事情。
  • 没问题 - 我已经尝试过您使用左连接发布的代码,但出现“不支持连接表达式”错误,因此它不会执行。 (它使用右连接执行)。加盟方面是我理解比较薄弱的地方,所以我会进一步消化和回顾。感谢您的帮助。
【解决方案2】:

感谢您的帮助。答案是:

SELECT Dates.Dates, Enquiries.[Event Sub Category], Financials.ActualIncome, Financials.EstimatedIncome

FROM Dates LEFT JOIN (SELECT
                     Enquiries.[Date Event Start],
                     Enquiries.[Event Sub Category],
                     Financials.ActualIncome,
                     Financials.EstimatedIncome
                   FROM
                   Enquiries INNER JOIN Financials

                   ON Enquiries.ID = Financials.[Enquiry ID] )  AS sub ON Dates.Dates= sub.[Date Event Start];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多