Order by Clause conflicts with distinct in Excel VBA? - sql

I can't figure out how to get past this error. I've seen how to do it when selecting one field, but not more than one. Can any SQL guru's out there give advice?
SELECT [Tool Name], MAX([Tool Start Time]) AS [Last Run]
FROM [Sheet1$]
GROUP BY [Tool Name]
ORDER BY [Tool Start Time] DESC
The first three lines work, but when trying to order the dates, I get the error.

Related

Query keeps showing all records instead of a criteria

I have a very simple Select query in access. I have created a report from the query, where there are two date fields on the form for the user to fill and then a button to preview that report. But it keeps showing all of the records instead of showing only the ones within the range. What might be wrong with the query?
SELECT Marketics.Agent, Marketics.[Policy Number], Marketics.[Policy Status], Marketics.Decision, Marketics.[Old Premium], Marketics.[New Premium], Marketics.Difference, Marketics.Case
FROM Marketics
WHERE [Marketics].[Date Completed]>=[forms]![Policies Worked]![from]<=[forms]![Policies Worked]![to];
Consider:
SELECT * FROM Marketics
WHERE [Date Completed] >= [forms]![Policies Worked]![from] AND [Date Completed] <= [forms]![Policies Worked]![to]
Or
SELECT * FROM Marketics
WHERE [Date Completed] BETWEEN [forms]![Policies Worked]![from] AND [forms]![Policies Worked]![to]

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

I am trying to produce a database to manage maintenance of equipment. I have two tables:
One (Inventory) containing details of each piece of equipment, including Purchase Date and Service Period,
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.
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
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.

How to group totals

I am trying to group by category - But the SQL I am using is grouping them all by date.
Example:
If a user selects a date range of 01/04/17 - 20/04/17 it will show them total number found under category A
Whats actually happening:
The results are showing Category A 10 times and showing me the total number of each date rather than a complete grouped total
Hope this makes sense
SELECT tbl_ComplaintsCoded.CauseManager, Count(tbl_ComplaintsCoded.CauseManager) AS CountOfCauseManager, tbl_ComplaintsCoded.[Account Number], tbl_ComplaintsCoded.TouchCSM, tbl_ComplaintsCoded.[Mail Date]
FROM tbl_ComplaintsCoded
GROUP BY tbl_ComplaintsCoded.CauseManager, tbl_ComplaintsCoded.[Account Number], tbl_ComplaintsCoded.TouchCSM, tbl_ComplaintsCoded.[Mail Date]
HAVING (((tbl_ComplaintsCoded.TouchCSM)=[Forms]![frm_Central_Reporting]![Combo209]) AND ((tbl_ComplaintsCoded.[Mail Date]) Between [Forms]![frm_Central_Reporting]![Text204] And [Forms]![frm_Central_Reporting]![Text206]));
this should get what you want:
SELECT tbl_ComplaintsCoded.CauseManager, Count(tbl_ComplaintsCoded.CauseManager) AS CountOfCauseManager, tbl_ComplaintsCoded.[Account Number], tbl_ComplaintsCoded.TouchCSM, tbl_ComplaintsCoded.[Mail Date]
FROM tbl_ComplaintsCoded
WHERE tbl_ComplaintsCoded.TouchCSM = [Forms]![frm_Central_Reporting]![Combo209]
AND (tbl_ComplaintsCoded.[Mail Date] BETWEEN [Forms]![frm_Central_Reporting]![Text204] AND [Forms]![frm_Central_Reporting]![Text206])
GROUP BY tbl_ComplaintsCoded.CauseManager
HAVING CountOfCauseManager > 0;
Also, please read: WHERE vs HAVING

Date Range in an Access Crosstab

Trying to get a Crosstab to bring up a prompt when a query is opened to allow a date range (start and end) to be input (dd-mm-yyyy) so that only this data comes back when the query is ran.
Currently sitting on the following code;
TRANSFORM Count(AlphaData.[Invoice]) AS CountOfInvoice
SELECT AlphaData.[Reason], Count(AlphaData.[Invoice]) AS [Total Of Invoice]
FROM AlphaData
WHERE ((AlphaData.[DateRaised]) Between AlphaData.[DateRaised] And AlphaData.[DateRaised])
GROUP BY AlphaData.[Reason]
PIVOT Format([DateRaised],"Short Date");
But cannot for the life of me get around the "MS Access DB engine does not recognise 'Alphadata.[DateRaised:]' as a valid field name or expression" issue.
The "WHERE" portion of the query does work in other queries, but it just goes to pot when it's applied in a crosstab.
Any suggestions?
It seems a bit mixed up. How about:
PARAMETERS
[From Date:] DateTime,
[To Date:] DateTime;
TRANSFORM
Count(*) AS CountOfInvoice
SELECT
AlphaData.[Reason],
Sum(AlphaData.[Invoice]) AS [Total Of Invoice]
FROM
AlphaData
WHERE
AlphaData.[DateRaised] Between [From Date:] And [To Date:]
GROUP BY
AlphaData.[Reason]
PIVOT
Format([DateRaised],"Short Date");
You need to add the parameters to the query:
PARAMETERS [Start Date] DateTime, [End Date] DateTime;
TRANSFORM Count(AlphaData.Invoice) AS CountOfInvoice
SELECT AlphaData.Reason, Count(AlphaData.Invoice) AS [Total Of Invoice]
FROM AlphaData
WHERE (((AlphaData.DateRaised) Between [Start Date] And [End Date]))
GROUP BY AlphaData.Reason
PIVOT Format([DateRaised],"Short Date");
(note: parameter added as the first line, and then used in the Between statement).
If you're using the graphical interface you need to look for the Parameter option:
and enter your parameters in the dialog box:
I didn't realise this would happen with a cross-tab as you can just type the parameter in for a select query:
SELECT Invoice, Reason, DateRaised
FROM AlphaData
WHERE DateRaised=[Start Date]

SQL between 2 dates not returning correct results

I am using the query below and I would like to get the rows where "[Last Update Date]" is in either 2015 or 2016.
SELECT [NPI]
,[Entity Type Code]
,[Replacement NPI]
,[Employer Identification Number (EIN)]
,[Provider Organization Name (Legal Business Name)]
,[Provider Last Name (Legal Name)]
,[Provider First Name]
,[Provider Middle Name]
,[Provider Name Prefix Text]
,[Provider Name Suffix Text]
,[Provider Credential Text]
,[Provider Enumeration Date]
,[Last Update Date]
,[Healthcare Provider Taxonomy Code_1]
FROM [Database].[dbo].[NPIInfo]
WHERE[Healthcare Provider Taxonomy Code_1] in ('122300000X', '1223G0001X','1223P0221X','1223P0700X')
AND ([Last Update Date] BETWEEN '2015/01/01' AND '2016/12/31' )
order by [Last Update Date]
I don't receive any results when I run the code above. But if I run it with this "AND" statement I get results:
AND [Last Update Date] like '%2015%' or [Last Update Date] like '%2016%'
This result gives me 500,000 + rows.
If I run it this way per year I get way less results:
AND [Last Update Date] like '%2015%'
Any idea what I am doing wrong here? The last 2 And statements are giving me different results TIA
TRY
WHERE CONVERT(DATETIME, [Last Update Date] , 103) BETWEEN '2015/01/01' AND '2016/12/31'
Check this page for the different formats
http://www.sql-server-helper.com/sql-server-2008/sql-server-2008-date-format.aspx
EDIT: Apparently I'm wrong here. Leaving the answer for reference as to what is not the problem. However, the CAST code might work anyway.
First, you can't use BETWEEN with text data, you have to do it with a datetime or numeric format. If [Last update Date] is text you'll need to convert it to datetime before you can do anything with it. It would be best to change your actual data's format, but if you can't for some reason this may work:
AND (CAST([Last Update Date] as datetime)
BETWEEN CAST('2015/01/01' as datetime) AND CAST('2016/12/31' as datetime))
Regarding your like '%2015%' statements, the wildcard condition you're using is specifically for text data; that's why it works at all. The different row amounts are because the first like is looking for both 2015 and 2016, while the second one is looking for only 2015.