SQL Select Where Between statement missing results that should be there? - sql

I apologize if this question has already been asked, but I couldn't find anything on it.
Basically, my accounting department runs a report every month to pull up all orders from a specific client for the previous month. My problem is that I have orders that are not showing up in these reports. The only similarities I can find in the orders that are missing is that if there are 2 or more sequential order numbers, one or more of them will not be picked up by the report if most other fields are the same.
When I ran the report over a single 24 hour period, any orders that were missing from the month-long report would show up for that day.
This is the code I'm using for the query:
SELECT paydetail.ord_hdrnumber as ord_hdrnumber,
NULL As TotalRevenue,
paydetail.pyt_itemcode As Item,
NULL As ItemRevenue,
pyd_amount As ItemPay,
paydetail.asgn_type,
paydetail.asgn_id, ord_driver1,
ord_revtype1, pyt_description As ItemDesc,
pyt_basis As ItemBasis
FROM paydetail
LEFT OUTER JOIN payheader ON pyh_pyhnumber = pyh_number
JOIN orderheader on orderheader.ord_hdrnumber = paydetail.ord_hdrnumber
JOIN paytype on paytype.pyt_itemcode = paydetail.pyt_itemcode
WHERE ord_billto = #billto
AND ord_startdate BETWEEN #startdate + ' 00:00:00' AND #enddate + ' 23:59:59'
AND paydetail.pyt_itemcode NOT IN ('TCKEVE','TCKEXP','TCKDEB')
UNION ALL
SELECT invoicedetail.ord_hdrnumber as ord_hdrnumber,
ivh_totalcharge As TotalRevenue,
invoicedetail.cht_itemcode As Item,
ivd_charge As ItemRevenue,
NULL As ItemPay,
NULL As asgn_type,
NULL as asgn_id,
NULL as ord_driver1,
ord_revtype1,
[cht_description] As ItemDesc,
[cht_basis] As ItemBasis
FROM invoicedetail
LEFT OUTER JOIN invoiceheader ON invoiceheader.ivh_hdrnumber = invoicedetail.ivh_hdrnumber
JOIN orderheader on orderheader.ord_hdrnumber = invoicedetail.ord_hdrnumber
JOIN chargetype ON chargetype.cht_itemcode = invoicedetail.cht_itemcode
WHERE ivh_billto = #billto
AND ord_startdate BETWEEN #startdate + ' 00:00:00' AND #enddate + ' 23:59:59'
ORDER by ord_hdrnumber

Related

daily incremental results on table where transaction date <= #Date parameter

specifically looking for General Leger results. This means that I can't sum up transactions for specfic dates, or cant run Between date.
to get the results for say, today I would need to query the table for all transactions <= #Today.
That said, i am tasked with running this for every single day in 2020 thus far. is there a method to do this where i dont have to manually run for each day myself?
Query example:
glo.GLValue
, Sum(UnitCR) AS 'Credit'
, Sum(UnitDR) AS 'Debit'
, sum(FirmCR) AS 'FirmCredit'
, sum(FirmDR) AS 'FirmDebit'
FROM glacct ga
inner join gldetail gd on gd.glacct = ga.AcctIndex
inner join glnatural gn on ga.glnatural = gn.GLNaturalID
inner join glunit glu on ga.glunit = glu.GLUnitID
inner join gloffice glo on ga.GLOffice = glo.GLOfficeID
WHERE gn.GLNat IN ('11001','11002','11003','11005','11007','11011','11016','11019','11020','11021','11022','11024','11025','11026','11027','11032','11033',
'11034','11035','11036','11037','11040','11041','11042','11043','11044','11050','11051','11052','11053','11190','11199','11201','11202','11203','11204',
'11205','11206','11207','11301','11603','11700','11705','11801','11802','11803','11804','11806','11807','11808','11809','11901')--,'22001')
AND gd.PostDate <= #Yesterday
GROUP BY
glo.GLValue
Create a sub-table that give the sums for each PostDate and GLValue similar to above but also grouped on PostDate, then join that to your select above, e.g.
inner join gloffice glo on ga.GLOffice = glo.GLOfficeID
inner join ( ... new grouped select here ...) gs on gs.GLValue = glo.GlValue and gs.PostDate < gd.PostDate
Now you should be able to sum the gs values:
, Sum(gs.Credit) as Credit
, Sum(gs.Debit) as Debit
etc.

How to remove duplicate SQL rows based off 1 column by comparing 2 different date columns?

I have a query that joins multiple tables/views and displays rows that are identified by a column named VIN. I want to only show the VIN one time based off of the most recent date from 2 different date fields (OPEN DATE & INVOICE DATE) IF both dates have a Value.
If Invoice Date is Null, show the row that has the most recent Open Date for that VIN. For example, if I have 3 rows for VIN='XY123456' and
Row 1 shows Open Date 3/1/2019 and Invoice Date NULL, and
Row 2 shows Open Date 3/15/2019 and Invoice Date 3/28/2019, and
Row 3 shows Open Date 4/1/2019 and Invoice Date 4/5/2019,
I want to return Row 1 since the Invoice Date is NULL and it is the most recent Open Date for that VIN.
Had there been an Invoice Date for Row 1, we would return the row with the most recent date from either date column.
I have tried ELSE clause and COALASCE without success. I also tried doing a subquery to use MAXDATE.
SELECT RO.[RepairOrderID]
,RO.[CompanyName]
,CUS.CustomerKey
,UN.UnitNumber AS 'UNIT #'
,ISNULL(UC.[Tag #],'') AS 'S #'
,UN.Year
,UN.Make
,UN.Model
,UN.VIN
,ROS.[RepairOrderStatus] AS 'STATUS'
,RO.RepairOrderNumber AS 'RO #'
,CONVERT(VARCHAR(2),DATEPART(month, RO.[OpenDate]))
+ '/'+ CONVERT(VARCHAR(2),DATEPART(DAY, RO.[OpenDate]))
+ '/' + CONVERT(VARCHAR(4),DATEPART(YEAR, RO.[OpenDate]))
'OPEN DATE'
,CONVERT(VARCHAR(2),DATEPART(month, ROI.InvoiceDate))
+ '/'+ CONVERT(VARCHAR(2),DATEPART(DAY, ROI.InvoiceDate))
+ '/' + CONVERT(VARCHAR(4),DATEPART(YEAR, ROI.InvoiceDate))
'INVOICE DATE'
FROM [ProfitMaster].[dbo].[RepairOrder] RO with (nolock)
INNER JOIN [ProfitMaster].[dbo].[vwAC_SSR_Customer] CUS with (nolock)
ON CUS.CustomerID = RO.CustomerID
INNER JOIN [ProfitMaster].[dbo].[RepairOrderStatus] ROS with (nolock)
ON ROS.RepairOrderStatusID = RO.RepairOrderStatusID
LEFT OUTER JOIN [ProfitMaster].[dbo].[RepairOrderInvoice] ROI with (nolock)
ON ROI.RepairOrderID = RO.RepairOrderID
LEFT OUTER JOIN [ProfitMaster].[dbo].[vwSR_SSR_Unit] UN with (nolock)
ON UN.UnitInventoryID = RO.UnitInventoryID
LEFT OUTER JOIN [ProfitMaster].[dbo].[vwSR_SSR_UnitCharacteristics] UC with (nolock)
ON UC.UnitInventoryID = Ro.UnitInventoryID
WHERE ((ROS.RepairOrderStatus IN ('OPEN')
OR (ROS.RepairOrderStatus = 'QUOTE' AND RO.OpenDate >= (getDate()- 90)))
OR (ROS.RepairOrderStatus = 'INVOICED' AND ROI.InvoiceDate > '2019-01-01 00:00:00.000'))
AND (CUS.InternalAccount = '0' AND CUS.InternalLRCustomer = '0')
Results Sample:

How to fix "Conversion from string "August" to type 'Date' is not vaid in SSRS

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?

Use last available currency rate by date available to calculate totals

I am trying to convert currency rates on orders.
The currency rates table is updated daily End of day for that particular day, however an order can be created earlier in the day, and as a result the rate will not be reflected with the current query. How would I add case statements and modify the query where by if the currency rate for the day does not exist use the last currency date available (within the table).
#Curr is the desired currency code. Could be 'USD', 'GBP' etc.
SELECT OrderNumber
,(CASE WHEN #Curr<>cur.code THEN
o.price * (SELECT Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
AND xr.Date= ISNULL((SELECT TOP 1 CAST(Crtd_DateTime AS Date) FROM ApDoc apdoc
WHERE apdoc.PONbr = o.OrderNumber AND apdoc.PONbr>''
ORDER BY apdoc.Crtd_DateTime DESC),o.orderdate)
)
ELSE o.price
END ) as o.price
from orders o
join currency c on c.curcode = o.curcode
Why not this:
...
o.price * (SELECT TOP 1 Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
ORDER BY xr.Date DESC)
...
If there are future dates in the xchangeRates table, all you have to do is add an additional filter to the WHERE clause to limit xr.Date to <= today.
EDIT: to handle this requirement:
if the invoice was created in the apdoc the it uses that Date for the
exchange rate, but if not then it uses the date the order was created.
forget your subselect to apDoc and JOIN it to orders in the outer query instead:
LEFT OUTER JOIN apDoc
ON apdoc.PONbr = o.OrderNumber
And then do this for your subquery instead of what I have above:
o.price * (SELECT TOP 1 Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
AND xr.Date =< COALESCE(CAST(apdoc.Crtd_DateTime AS Date),o.OrderDate)
ORDER BY xr.Date DESC)
nb: I CAST Crtd_DateTime AS Date because you did it in your code, and for all I know it's a varchar, but if it's a Datetime datatype, then the cast isn't necessary in my solution.

Adding zero values to report

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).