The below is an example of what will output when you run the query open: select A.DispatchNote, A.MStockCode, A.NComment
from MdnMaster
MdnMaster.DispatchNote
MdnMaster.MStockCode
MdnMaster.NComment
12345/001
CAL2-01234-010-50L
12345/001
FREIGHT
12345/001
1 Parcel
12345/001
Trk# 1Z8R9V80013141323 - 5 lb
12345/001
Trk#: 1Z8R9V900381868191 -- 18 lb
12345/001
SHP 21401
12345/002
CAL3-0121-020-50L
12345/002
FREIGHT
12345/002
2 Parcels
12345/002
Trk# 1Z8R9V80013141323 - 5 lb
12345/002
Trk#: 1Z8R9V900381868191 -- 18 lb
12345/002
SHP 2140
I'm trying to do a query that'll grab just the first tracking number in the list. and ignore the second (or sometimes third they have)
The database has blank NComment lines when there's an MStockCode, and then the MStockCode lines are blank for every NComment line so I don't know what I'm doing.
What I have so far:
SELECT
m.DispatchNote,
MAX(d.MStockCode) as StockCode,
MAX(case when d.NComment like 'Trk%' then d.NComment end) as NComment,
MAX(m.CustomerPoNumber) as CustomerPO
FROM MdnMaster AS m
LEFT OUTER JOIN MdnDetail AS d on m.DispatchNote = d.DispatchNote
AND (d.NComment LIKE 'Trk%' OR d.MStockCode is not null)
and m.Customer = 'LAWSON'
and d.MLineShipDate =
case
when datepart(weekday, getdate() -1) = '7'
then DATEADD(hh,0,dateadd(DAY, datediff(day, 0, getdate()),-2)) -- if yesterday was Saturday, set to Friday
when datepart(weekday, getdate() -1) = '1'
then DATEADD(hh,0,dateadd(DAY, datediff(day, 0, getdate()),-3)) -- if yesterday was Sunday, set to Friday
else DATEADD(hh,0,dateadd(DAY, datediff(day, 0, getdate()),-1))
end
GROUP BY m.DispatchNote
My issue is that it gives me nothing since I only know how to ask it explicitly that I want the lines that aren't blank. How do I fix it?
EDIT: I should mention that all of the information comes from the MdnMaster Table (which is A) and MLineShipDate will come from B (MdnDetail). I omitted that information because I didn't think it was pertinent to the question at hand.
An example of what I want to see FROM above:
MdnMaster.DispatchNote
MdnMaster.MStockCode
MdnMaster.NComment
12345/001
CAL2-01234-010-50L
Trk# 1Z8R9V80013141323 - 5 lb
Here's a quick way to get some results. Hopefully, it will set you on the right path.
I'm assuming you can specify a second column to determine the order of the comments. Replace all instances of Line below with the actual column name.
Select
m1.DispatchNote,
m3.MStockCode,
m1.NComment
From
MdnMaster m1
Inner Join (
Select DispatchNote, Min(Line) as Line
From MdnMaster
Where NComment like 'Trk%'
Group by DispatchNote ) m2
on m1.DispatchNote = m2.DispatchNote and m1.Line = m2.Line
Inner Join (
Select DispatchNote, Max(MStockCode) as MStockCode
From MdnMaster
Group by DispatchNote ) m3
on m1.DispatchNote = m3.DispatchNote
One approach use a cross apply together with select top 1 to retrieve the tracking number.
select M.DispatchNote, M.MStockCode, TRK.NComment
from MdnMaster M
cross apply (
select top 1 M2.NComment
from MdnMaster M2
where M2.DispatchNote = M.DispatchNote
and M2.NComment LIKE 'Trk# %'
-- order by ?
) TRK
where M.MStockCode <> ''
Another approach is to join to a subselect that selects all tracking numbers and assigns row numbers withing each group. The final select would limit itself to those tracking numbers where row number = 1.
select M.DispatchNote, M.MStockCode, TRK.NComment
from MdnMaster M
join (
select M2.DispatchNote, M2.NComment,
row_number() OVER(PARTITION BY M2.DispatchNote order by (select null)) as RN
from MdnMaster M2
where M2.NComment LIKE 'Trk# %'
) TRK ON TRK.DispatchNote = M.DispatchNote
where M.MStockCode <> ''
and TRK.RN = 1
See this db<>fiddle for examples of both.
If there is a chance that there is no tracking number, but you still want to include the other results, change cross apply to outer apply in the first query, or the join to a left join in the second. A cross apply is like an inner join to a subselect, while an outer apply is like a left join.
If you have criteria that prefers one tracking number over another, include it in the order by clause of the subselect in the first query, or replace the order by (select null) placeholder clause in the second. Otherwise, an arbitrary tracking number will be selected.
Related
I would like to know what can you do in the following scenario:
Lets say I am filtering on a date in the where clause (between eomonth(#StartDate) and eomonth(getdate()-1). I have a calculated column that is correct when I run the query without any filter, but the problem is that when I filter lets say #StartDate = 06/30/2017 then the calculations will obviously change. Is there any way of doing this?
The calculated column is a windowing function.
Edited:
I have added a picture of the data. So I am using a windowing function to calculate the agentfourmonthperiod. You will see that it sums the units for that month and the 3 previous months. This I dont want to change when filtering. So the units and agentfourmonthperiod columns should stay exactly the same after filtering on the #StartDate. Please see data below:
I want to design an SSRS report that the user will be filtering on the #StartDate, but then it should show the calculation as it does when no filter in used.
Hope this makes sense. Otherwise I can add the code. Its just quite long though.
Code:
WITH DATA
AS
(
SELECT
EOMONTH(SubmissionDates.original_date_c) AS IntakeMonth,
ProvincialArea.SAD_ProvMananger AS ProvManager,
RegionalArea.SAD_RegMananger AS RegManager,
SalesArea.SAD_SalesManager AS AreaSalesManager,
ConsultantUserExt.name AS Consultant,
COUNT(LeadsLink.LeadsID) OVER(PARTITION BY ConsultantUserExt.name, EOMONTH(SubmissionDates.original_date_c,0) ORDER BY EOMONTH(SubmissionDates.original_date_c,0)) AS Unit,
ROW_NUMBER() OVER(PARTITION BY ConsultantUserExt.name, EOMONTH(SubmissionDates.original_date_c,0) ORDER BY EOMONTH(SubmissionDates.original_date_c,0)) AS rn
FROM Import.OobaApplication as Application
LEFT OUTER JOIN Import.OobaApplicant applicant ON application.ApplicationID = applicant.ApplicationID
AND applicant.PrincipleApplication = 'Y'
LEFT OUTER JOIN usr_userext_cstm ON Application.Consultant = usr_userext_cstm.comcorp_key_c
or Application.Consultant = usr_userext_cstm.deal_maker_key_c
or Application.Consultant = usr_userext_cstm.ops_key_c
LEFT OUTER JOIN usr_userext AS ConsultantUserExt ON usr_userext_cstm.id_c = ConsultantUserExt.id AND ConsultantUserExt.deleted = 0
LEFT OUTER JOIN usr_userext_cstm AS ConsultantUserExtCstm on ConsultantUserExt.id = ConsultantUserExtCstm.id_c
LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON ConsultantUserExtCstm.sad_provincialmanager_c = ProvincialArea.ID
LEFT OUTER JOIN CapcubedInternalDB.dbo.RegionalArea AS RegionalArea ON ConsultantUserExtCstm.sad_regionalmanager_c = RegionalArea.ID
LEFT OUTER JOIN CapcubedInternalDB.dbo.SalesArea AS SalesArea ON ConsultantUserExtCstm.sad_salesmanager_c = SalesArea.ID
LEFT OUTER JOIN CapcubedInternalDB.dbo.LeadsLink AS LeadsLink ON Application.ApplicationID = LeadsLink.GroupCode
LEFT OUTER JOIN suitecrmprod.dbo.leads AS SuiteLeads ON LeadsLink.LeadsID = SuiteLeads.ID
--Latest Bank Submission
LEFT OUTER JOIN (SELECT
bankSub.ApplicationID As BankSubAppID, bankSub.SubmissionDate,
bankSub.Bank, bankSub.RequiredLoanAmount,
bankSub.BankCode AS BankSubBankCode
FROM Import.OobaBankSubmission bankSub
LEFT OUTER JOIN Import.OobaBankSubmission later ON bankSub.ApplicationID = later.ApplicationID
AND bankSub.SubmissionDate > later.SubmissionDate
WHERE later.applicationID IS NULL) AS BankSub ON Application.ApplicationID = BankSub.BankSubAppID
LEFT OUTER JOIN ccrep_calendar_cstm AS SubmissionDates ON CONVERT(VARCHAR(10),BankSub.SubmissionDate,101) = SubmissionDates.original_date_c
WHERE SubmissionDates.cc_date_c BETWEEN COALESCE(EOMONTH(#StartDate), '01/31/2016') AND COALESCE(#EndDate, GETDATE(), -1)
AND ConsultantUserExtCstm.consultantstatus_c NOT LIKE 2
)
SELECT *
INTO #Rn
FROM DATA
WHERE rn = 1
SELECT i.IntakeMonth, c.ProvManager, c.RegManager, c.AreaSalesManager, c.Consultant, COALESCE(#Rn.Unit, 0) AS Unit
INTO #FillData
FROM (SELECT DISTINCT IntakeMonth FROM #Rn) AS i
CROSS JOIN
(SELECT DISTINCT Consultant, ProvManager, RegManager, AreaSalesManager FROM #Rn) AS c
LEFT OUTER JOIN #Rn ON #Rn.IntakeMonth = i.IntakeMonth AND #Rn.Consultant = c.Consultant
ORDER BY Consultant, IntakeMonth
SELECT
IntakeMonth,
Consultant,
Unit,
SUM(Unit) OVER(PARTITION BY Consultant ORDER BY Consultant ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS agentfourmonthperiod
FROM #FillData
WHERE ('(All)' IN (#ProvincialManager) OR (ProvManager IN (#ProvincialManager)))
AND ('(All)' IN (#RegionalManager) OR (RegManager IN (#RegionalManager)))
AND ('(All)' IN (#AreaSalesManager) OR (AreaSalesManager IN (#AreaSalesManager)))
AND ('(All)' IN (#Consultant) OR (Consultant IN (#Consultant)))
DROP TABLE #Rn
DROP TABLE #FillData
You could of course remove any filter on dates from the query and apply them directly in the tablix of your report. Obvously, this means that SQL Server has to return all the data each time the report is run, so I guess that this isn't what you want.
For the window function to have access to the previous 3 rows, you will have to include the previous 3 months in your calculation. To achieve this, change the first condition in the WHERE clause in the cte (data) to something like this:
SubmissionDates.cc_date_c
BETWEEN
ISNULL(DATEADD(month, DATEDIFF(month, 0, #StartDate)-3, 0), '01/10/2015')
AND
ISNULL(#EndDate, DATEADD(day, DATEDIFF(day, 0, GETDATE())-1, 0))
As I thought that your date filter logic was wrong, I changed it to include the dates from the beginning of the month rather than from the end.
Now that the previous 3 months are included, we can apply a filter in the end to exclude the previous months from display, but this has to be done after using the window function, for example with another cte:
WITH calc AS (
SELECT
IntakeMonth,
Consultant,
Unit,
SUM(Unit) OVER(PARTITION BY Consultant ORDER BY Consultant ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS agentfourmonthperiod
FROM #FillData
WHERE ('(All)' IN (#ProvincialManager) OR (ProvManager IN (#ProvincialManager)))
AND ('(All)' IN (#RegionalManager) OR (RegManager IN (#RegionalManager)))
AND ('(All)' IN (#AreaSalesManager) OR (AreaSalesManager IN (#AreaSalesManager)))
AND ('(All)' IN (#Consultant) OR (Consultant IN (#Consultant)))
)
SELECT IntakeMonth, Consultant, Unit, agentfourmonthperiod
FROM calc
WHERE IntakeMonth >= ISNULL(EOMONTH(#StartDate), '01/31/2016')
SELECT
a.ItemCode,
SUM(a.NoOfApplication) AS NoOfApplication,
SUM(a.NoOfAccomplished) AS NoOfAccomplished,
SUM(a.NoOfPending) AS NoOfPending,
SUM(a.NoOfDocumentCompliance) AS NoOfDocumentCompliance,
a.[Year]
FROM
(SELECT
ItemCode,
COUNT(am.ReferenceNumber) AS NoOfApplication,
COUNT(TNA.NoOfAccomplished) AS NoOfAccomplished,
COUNT(TNP.NoOfPending) AS NoOfPending,
SUM(FDC.NoOfDocumentCompliance) AS NoOfDocumentCompliance,
DATENAME(month, ad.applicationdate) AS [Year]
FROM
AppTypes at
INNER JOIN
AssessmentMainDetails am ON at.Category = am.Category
INNER JOIN
InspectionProcesses i ON am.ReferenceNumber = i.ReferenceNo
LEFT JOIN
(SELECT
COUNT(Status) AS NoOfDocumentCompliance,
ReferenceNumber, Status
FROM
ApplicationStatus
WHERE
Status = 'For Document Compliance'
GROUP BY
ReferenceNumber, Status) AS FDC ON FDC.ReferenceNumber = i.ReferenceNo
LEFT JOIN
(SELECT
COUNT(ReferenceNo) AS NoOfAccomplished,
ReferenceNo
FROM
InspectionProcesses
WHERE
DateOfInspection <> ''
GROUP BY
ReferenceNo) AS TNA ON TNA.ReferenceNo = i.ReferenceNo
LEFT JOIN
(SELECT
COUNT(ReferenceNo) AS NoOfPending, ReferenceNo
FROM
InspectionProcesses
WHERE
DateOfInspection = ''
GROUP BY
ReferenceNo) AS TNP ON TNP.ReferenceNo = i.ReferenceNo
INNER JOIN
ApplicationDetails ad on i.ReferenceNo = ad.ReferenceNumber
INNER JOIN
Companies c on ad.CompanyId = c.CompanyID
INNER JOIN
Zones z on c.zonecode = z.zonecode
INNER JOIN
ZoneGroups zg on z.ZoneGroup = zg.ZoneGroupId
WHERE
DateOfInspection = ''
AND ad.ApplicationDate BETWEEN '2017-08-01' AND '2017-09-30'
AND zg.ZoneGroupCode = 'HO'
AND z.ZoneCode = 'VIDC'
GROUP BY
ItemCode, DATENAME(month, ad.applicationdate)) a
GROUP BY
a.ItemCode, a.[Year]
This my code, I already converted my date to get the month name. Please I need help
Look carefully. That giant derived table (a - nice meaningful name btw) has the same group by clause as the outermost query. So that means that [a] has a single row per ItemCode and datename(month, ad.applicationdate). Therefore, there is nothing to sum in your outer query since it is grouping by the same columns.
You also have the expression:
DateOfInspection = ''
which is highly suspicious based on the name of the column. What datatype is the DateOfInspection column? Doesn't sound like it should be string-based.
And lastly, the error message you posted sounds like it comes from SSRS and not sql server. Is that the case? Does your query run correctly from SSMS? Then the problem is in your report - and it would seem that you attempt to manipulate or interpret the Year column as a date (perhaps for sorting?). It also seems a bit short-sighted in your report design that your "Year" column is actually the name of a month and that your resultset does not include the year in some fashion. What happens when your data spans more than twelve months? And how do you intend to sort your report when you have month name but not month number?
I am trying to return data that will ultimately populate a label.
Each label is going onto a box, and the box can only have 4 items in it.
If a delivery has more than 4 items, then I need one label per 4.
Each row of data returned will populate one label, so if the delivery contains 9 items, then I need 3 rows of data returned.
Below is my current query, which is returning all items into a comma separated value using Stuff.
I want it so the first 4 rows for the delivery return in the first row, then the next 4 in the second and so on.
My Field LineOrd returns correctly if there are more than 4 lines on the dispatch.
select Distinct
delivery_header.dh_datetime,
delivery_header.dh_number,
order_header.oh_order_number as 'Order No',
order_header_detail.ohd_delivery_name,
order_header_detail.ohd_delivery_address1,
order_header_detail.ohd_delivery_address2,
order_header_detail.ohd_delivery_address3,
order_header_detail.ohd_delivery_town,
order_header_detail.ohd_delivery_county,
order_header_detail.ohd_delivery_postcode,
order_header_detail.ohd_delivery_country,
STUFF((Select ', '+convert(varchar(50),convert(decimal(8,0),DL.dli_qty))+'x '+OLI.oli_description
from delivery_header DH join delivery_line_item DL on DL.dli_dh_id = DH.dh_id join order_line_item OLI on OLI.oli_id = DL.dli_oli_id
Outer APPLY
(select
case when DelCurLine.CurLine <= 4
then '1'
Else
Case when DelCurLine.CurLine <= 8
then '2'
Else '3'
End
End +'-'+order_header.oh_order_number as LineOrd) as StuffLineOrder
Where DH.dh_id = delivery_header.dh_id And StuffLineOrder.LineOrd = LineOrder.LineOrd
FOR XML PATH('')),1,1,'') as Items,
LineOrder.LineOrd
from delivery_header
join delivery_line_item on delivery_line_item.dli_dh_id = delivery_header.dh_id
join order_line_item on order_line_item.oli_id = delivery_line_item.dli_oli_id
join order_header on order_header.oh_id = order_line_item.oli_oh_id
join order_header_detail on order_header_detail.ohd_oh_id = order_header.oh_id
join variant_detail on variant_detail.vad_id = order_line_item.oli_vad_id
join stock_location on stock_location.sl_id = order_line_item.oli_sl_id
Outer APPLY
(select count(DLI.dli_id) CurLine from delivery_line_item DLI where DLI.dli_dh_id = delivery_header.dh_id and DLI.dli_id <= delivery_line_item.dli_id)
as DelCurLine
Outer APPLY
(select
case when DelCurLine.CurLine <= 4
then '1'
Else
Case when DelCurLine.CurLine <= 8
then '2'
Else '3'
End
End +'-'+order_header.oh_order_number as LineOrd) as LineOrder
Outer APPLY
(select convert(varchar(50),convert(decimal(8,0),delivery_line_item.dli_qty))+'x '+order_line_item.oli_description as LineName) as LineName
where
delivery_header.dh_datetime between #DateFrom and #DateTo
and stock_location.sl_id = #StockLoc
and (order_header.oh_order_number = #OrderNo or #AllOrder = 1)
order by
delivery_header.dh_datetime,
delivery_header.dh_number,
order_header.oh_order_number,
order_header_detail.ohd_delivery_name,
order_header_detail.ohd_delivery_address1,
order_header_detail.ohd_delivery_address2,
order_header_detail.ohd_delivery_address3,
order_header_detail.ohd_delivery_town,
order_header_detail.ohd_delivery_county,
order_header_detail.ohd_delivery_postcode,
order_header_detail.ohd_delivery_country
You can use ROW_NUMBER() with a division by 4. This truncate the decimal because numerator is an interger. This give you group number with a maximum of four row in each group. You can then adjust your query to use this group number in a "group by" clause to return grouped rows into a single one.
Exemple here :
SELECT RawData.BoxGroup,
MIN(dh_datetime),
MIN(dh_number),
MIN(order_header.oh_order_number) as 'Order No'
--And so on
FROM
(SELECT BoxGroup = (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) - 1) / 4,
*
FROM [TableNameOrQuery]) AS RawData
GROUP BY RawData.BoxGroup
Hope this help.
I would like to display an output when a certain column which contain dates equals the last day of a month then another column which also contains other dates should equal the same date minus 1 day
SELECT
CASE WHEN s.audit_date <> null
THEN us.processing_date = s.audit_date - 1 END processing_date
, g.mobile_no
FROM customers cu
INNER JOIN gsm.mobile_no g ON g.id = cu.id;
but unfortunately this doesn't work..
There are a couple of problems that I can see with your query.
You are missing a comma after the s.audit_date to provide valid T-SQL syntax
In your CASE statement you are attempting to set a column value, just return the value you want.
select us.processing_date, s.audit_date,
CASE
WHEN s.audit_date = trunc(s.audit_date, 'MM') THEN s.audit_date - 1
END processing_date, g.mobile_no
from customers cu
inner join gsm.mobile_no g on g.id = cu.id
Among other things, I think you need an else clause and to fix the comparison to NULL:
select (case when s.audit_date is not null then s.audit_date - 1
else s.processing_date
end) as processing_date, g.mobile_no
from customers cu inner join
gsm.mobile_no g
on g.id = cu.id;
Ok This is a good question I think.
At the moment I have a report showing amount of tickets per machine and how much each machine made in ticket sales.
Some machines sell Zero tickets but they are not includded in my report.
Now i want to include them.
there is a full list of all machines in machconfig table which I could compare to the ticketssold table which also has a field corresponding to the machine that sold it.
So I guess I could find all of the machines that havent sold any tickets by looking for machine id's (MCHterminalid) that dont appear in the ticketssold table (TKtermid column)
here is the code I've got so far..
SELECT TKtermID,
MCHlocation,
Count (TKvouchernum) AS Totaltickets,
Cast(Sum(TKcomission) AS FLOAT) / 100 AS Total_Comission
FROM ticketssold(NOLOCK)
INNER JOIN machconfig (NOLOCK)
ON MCHterminalID = TKtermID
WHERE cfglocationcountry = 'UK'
AND dateadded BETWEEN Getdate() - 100 AND Getdate()
GROUP BY vstermID,
cfglocation
ORDER BY Total_comission DESC
Change the inner join between ticketssold and machconfig to a right outer join to get all machines, regardless of a match in the tickets sold table. The count of TKVouchernum will return the zeros for you:
SELECT TKtermID,
MCHlocation,
Count (TKvouchernum) AS Totaltickets,
Cast(Sum(TKcomission) AS FLOAT) / 100 AS Total_Comission
FROM ticketssold(NOLOCK)
RIGHT OUTER JOIN machconfig (NOLOCK)
ON MCHterminalID = TKtermID
WHERE cfglocationcountry = 'UK'
AND dateadded BETWEEN DateAdd(DAY, -100, GetDate()) AND Getdate()
GROUP BY vstermID,
cfglocation
ORDER BY Total_comission DESC
OCD Version not totally proofed (also killing me that table names are not included before the fields). Use the outer join in combination with COALESCE
SELECT
TKTermID TicketTerminalId,
MchLocation MachineLocation,
COALESCE(COUNT(TKVoucherNum),0) TotalTickets,
COALESCE(CAST(SUM(TKComission) AS float),0) / 100 TotalComission
FROM
MachConfig (NOLOCK)
LEFT JOIN
TicketsSold (NOLOCK)
ON
TKtermID = MCHterminalID
WHERE
CfgLocationCountry = 'UK'
AND
DateAdded BETWEEN DATEADD(DAY, -100, GETDATE()) AND GETDATE()
GROUP BY
VSTermID,
CfgLocation
ORDER BY
COALESCE(CAST(SUM(TKComission) AS float),0) / 100 DESC; --Do this in reporting!
Do not use inner joins because they will eliminate rows. I start my joins with the table that has all the data. In this case machconfig and then do a left outer join to the table with the problematic data ticketssold.
You may also want to think about doing your grouping on the report side for flexibility.
Finally got it working the way I want.. Here is the proper code:
SELECT MCHTerminalID, MCHLocation, ISNULL(CONVERT(varchar(16), batch.LastBatchIn, 103),
'Did not batch in') AS LastBatchIn,
ISNULL(COUNT(Ticket.VoucherNum), 0) AS TotalVouchers,
ISNULL(SUM(Ticket.Sale), 0) AS TotalGrossAmount, ISNULL(SUM(Ticket.Refund),0) AS TotalRefundAmount, ISNULL(SUM(Ticket.Comission),0) AS TotalComission
FROM termConfig AS config WITH (NOLOCK)
LEFT OUTER JOIN
(SELECT bsTerminalID, MAX(bsDateTime) AS LastBatchIn
FROM batchSummary WITH (NOLOCK)
WHERE bsDateTime BETWEEN getdate()-50 AND getdate()
GROUP BY bsTerminalID
)
AS batch
ON config.MCHTerminalID = batch.bsTerminalID
LEFT OUTER JOIN
(SELECT DISTINCT TKTermID,
TKVoucherNum AS VoucherNum,
CAST(TKGrossTotal AS float)/100 AS Sale,
CAST(TKRefundAmount AS float)/100 AS Refund,
CAST(TKComission AS float)/100 AS Comission
FROM TicketVouchers WITH (NOLOCK)
WHERE dateAdded BETWEEN getdate()-50 AND getdate()
)
AS Ticket
ON
config.MCHTerminalID = Ticket.TKTermID
WHERE
config.MCHLocationCountry = 'uk'
AND config.MCHProductionTerminal = 'Y'
GROUP BY config.MCHTerminalID, config.MCHLocation, LastBatchIn
ORDER BY TotalComission desc
You could UNION the 'zero' rows to your original e.g.
<original query here>
...
UNION
SELECT MCHterminalID,
MCHlocation,
0 AS Totaltickets,
0 AS Total_Comission
FROM machconfig
WHERE NOT EXISTS (
SELECT *
FROM ticketssold
WHERE MCHterminalID = TKtermID
)
(Review for hints).