Syntax of MS Access/SQL sub-query including aggregate functions

自闭症网瘾萝莉.ら 提交于 2019-12-24 07:09:58

问题


I am trying to produce a database to manage maintenance of equipment. I have two tables:

  1. One (Inventory) containing details of each piece of equipment, including Purchase Date and Service Period,
  2. One containing details of work done (WorkDone), including the date the work was carried out (Work Date).

I would like a query that displays the date that it should be next serviced. So far I have:

SELECT Max(DateAdd('m', [Inventory].[Service Period], 
                        [WorkDone].[Work Date])) AS NextServiceDate, 
       Inventory.Equipement
FROM Inventory INNER JOIN WorkDone ON Inventory.ID = WorkDone.Equipment
GROUP BY Inventory.Equipement

This works well as long as some work done has been registered for a given piece of equipment. If no work has been carried out I would like the NextServiceDate to also show

DateAdd('m',[Inventory].[Service Period], [Inventory].[Purchase Date])

However, I cannot work out how to get SQL/MS access to compare two values and only display the greater of the two. From reading around I think I should be able to do a sub-query, but I cannot work out how to phase it.

I've been trying to adapt @MikeTeeVee's answer from here: Is there a Max function in SQL Server that takes two values like Math.Max in .NET?. But I keep getting errors saying that query is not part of an aggregate function and I'm not certain what I doing wrong. For example, I tried:

SELECT Inventory.Equipement,
       (SELECT MAX(NSD_proxy) 
        FROM (VALUES 
             (Max(DateAdd('m', Inventory.[Service Period], WorkDone.[Work Date]))), 
                 (DateAdd('m', Inventory.[Service Period], Inventory.[Purchase Date]))) 
         AS FUNCTION(NSD_proxy)
        ) AS NextServiceDate,
FROM Inventory INNER JOIN WorkDone ON Inventory.ID = WorkDone.Equipment
GROUP BY Inventory.Equipement

which has some syntax error.


回答1:


Consider a LEFT JOIN to return matched or unmatched records where latter is filled with NULLs, and then run your aggregate, MAX, with an NZ():

SELECT Max(NZ(DateAdd('m', i.[Service Period], w.[Work Date]),
              DateAdd('m', i.[Service Period], i.[Purchase Date]))
          ) AS NextServiceDate, i.Equipement
FROM Inventory i LEFT JOIN WorkDone w ON i.ID = w.Equipment
GROUP BY i.Equipement



回答2:


You don't have to compare the two dates, just check if a WorkDone record exists to match the Inventory record.

You can use:

IIF(ISNULL(WorkDone.Equipment),
DateAdd('m',[Inventory].[Service Period],[Inventory].[Purchase Date]),
Max(DateAdd('m',[Inventory].[Service Period],[WorkDone].[Work Date])))
AS NextServiceDate

The rest of your query can remain as is.



来源:https://stackoverflow.com/questions/49576548/syntax-of-ms-access-sql-sub-query-including-aggregate-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!