I have two queries that work perfectly:
DECLARE @StartDate DATETIME = '2021-11-01 00:00:00';
DECLARE @EndDate DATETIME = '2022-03-16 23:59:59';
DECLARE @SalesEstimateTransactionTypeId INT = 16;
DECLARE @SalesOrderTransactionTypeId INT = 15;
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
COUNT(TransactionId) AS TransactionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= @StartDate
AND GeneralJournal.[TransactionDate] <= @EndDate
AND MasterRecord = 1
AND TransactionTypeId = @SalesEstimateTransactionTypeId
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
COUNT(DISTINCT TransactionId) AS ConversionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= @StartDate
AND GeneralJournal.[TransactionDate] <= @EndDate
AND MasterRecord = 0
AND TransactionTypeId = @SalesOrderTransactionTypeId
AND SEReferenceId > 0
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
Note that the second query returns distinct because it can return multiple values and we only want to count each TransactionId
once in that scenario. These return the following results:
ReportingMonth | MonthNumber | ReportingYear | TransactionCount |
---|---|---|---|
November | 11 | 2021 | 82 |
December | 12 | 2021 | 49 |
January | 1 | 2022 | 64 |
February | 2 | 2022 | 67 |
March | 3 | 2022 | 49 |
ReportingMonth | MonthNumber | ReportingYear | ConversionCount |
---|---|---|---|
November | 11 | 2021 | 42 |
December | 12 | 2021 | 27 |
January | 1 | 2022 | 31 |
February | 2 | 2022 | 50 |
March | 3 | 2022 | 24 |
I actually need to combine them like this:
ReportingMonth | MonthNumber | ReportingYear | TransactionCount | ConversionCount |
---|---|---|---|---|
November | 11 | 2021 | 82 | 42 |
December | 12 | 2021 | 49 | 27 |
January | 1 | 2022 | 64 | 31 |
February | 2 | 2022 | 67 | 50 |
March | 3 | 2022 | 49 | 24 |
I have tried pretty much everything I can think of - Unions, Joins, Subqueries - but so far nothing is quite right. This is the closest I can get:
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
SUM(CASE
WHEN TransactionTypeId = @SalesEstimateTransactionTypeId
AND MasterRecord = 1
THEN 1 ELSE 0
END) AS TransactionCount,
COUNT(CASE
WHEN TransactionTypeId = @SalesOrderTransactionTypeId
AND SEReferenceId > 0 THEN 1
END) AS ConversionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= @StartDate
AND GeneralJournal.[TransactionDate] <= @EndDate
AND TransactionTypeId IN (@SalesOrderTransactionTypeId, @SalesEstimateTransactionTypeId)
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
However, I am unable to find a way to get a Distinct value for the ConversionCount
. As a result it is returning the full count:
ReportingMonth | MonthNumber | ReportingYear | TransactionCount | ConversionCount |
---|---|---|---|---|
November | 11 | 2021 | 82 | 152 |
December | 12 | 2021 | 49 | 67 |
January | 1 | 2022 | 64 | 101 |
February | 2 | 2022 | 67 | 136 |
March | 3 | 2022 | 49 | 64 |
Can anyone guide me towards a way to combine the two query results whilst maintaining the Distinct on the conversion count? I must add that for it to work the answer must be compatible with both SQL Server and VistaDB the syntax of which is a subset of T-SQL because I am obliged to support both database engines with the same query.
EDIT - The Final Solution
Following on from Nick's excellent answer I was able embed the solution into my existing query code to ensure that there are results even for months with no records, shown here in case it helps anyone else:
DECLARE @StartDate DATETIME = '2021-11-01T00:00:00';
DECLARE @EndDate DATETIME = '2022-10-31T23:59:59';
DECLARE @SalesEstimateTransactionTypeId INT = 16;
DECLARE @SalesOrderTransactionTypeId INT = 15;
DECLARE @CurrentDate DATETIME;
DECLARE @Months TABLE(ReportingYear INT, MonthNumber INT, ReportingMonth VARCHAR (40));
-- Set the initial date
SET @CurrentDate = @StartDate
-- insert all dates into temp table
WHILE @CurrentDate <= @EndDate
BEGIN
INSERT INTO @Months VALUES(DATEPART(year, @CurrentDate), DATEPART(month, @CurrentDate), DATENAME(mm, @CurrentDate))
SET @CurrentDate = dateadd(mm, 1, @CurrentDate)
END;
SELECT ReportingMonth, ReportingYear, Coalesce(TransactionCount, 0) AS TransactionCount, Coalesce(ConversionCount,0) AS ConversionCount
FROM
(
SELECT months.[ReportingMonth], months.[ReportingYear], conversionData.[TransactionCount], conversionData.[ConversionCount]
FROM @Months months
LEFT JOIN
(
SELECT
ReportingMonth = DATENAME(mm, GeneralJournal.[TransactionDate]),
MonthNumber = DATEPART(mm, GeneralJournal.[TransactionDate]),
ReportingYear = DATEPART(yyyy, GeneralJournal.[TransactionDate]),
TransactionCount = SUM(CASE WHEN TransactionTypeId = @SalesEstimateTransactionTypeId AND GeneralJournal.[MasterRecord] = 1 THEN
1
ELSE
0
END
),
ConversionCount = COUNT(DISTINCT CASE WHEN GeneralJournal.[TransactionTypeId] = @SalesOrderTransactionTypeId
AND GeneralJournal.[SEReferenceId] > 0
AND GeneralJournal.[MasterRecord] = 0 THEN
GeneralJournal.[TransactionID]
END
)
FROM GeneralJournal
WHERE GeneralJournal.[TransactionDate] >= @StartDate
AND GeneralJournal.[TransactionDate] <= @EndDate
AND GeneralJournal.[TransactionTypeId] IN ( @SalesOrderTransactionTypeId, @SalesEstimateTransactionTypeId)
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm, GeneralJournal.[TransactionDate])
) as conversionData
ON months.[ReportingYear] = conversionData.[ReportingYear] AND months.[MonthNumber] = conversionData.[MonthNumber]
) AS data;
Your second query that is close, I think just has a couple of minor omissions.
MasterRecord = 0
in your ConversionCountCASE
statement.CASE
you should return TransactionID or NULL so you can still count distinct values.DISTINCT
inside of your ConversionCountCOUNT
.COUNT
. I assumed you will always have at one or moreNULL
s, so I just subtract 1 from theCOUNT(DISTINCT ...)
to compensate.(I can't be 100% on the syntax here without some example detail data to work with.)
Code