MS Access: match XRate to date - sql

I have three tables: Sales, Currency, Exchange Rate
I need the appropriate exchange rate for every sale and foreign currency transaction to be calculated to our local currency. The Exchange Rate Table has values for each foreign currency, but only for one date in each month, the last day.
I have attempted the following thus far, which works, if the sales date happens to be exactely the last day of a month:
SELECT
qry_SALES.Payment_ID,
qry_SALES.Product_Name,
qry_SALES.Sales,
qry_SALES.SalesDate,
qry_SALES.SalesCcy,
tbl_XRate.XRate_CHF,
tbl_XRate.XDate
FROM
qry_SALES INNER JOIN
(tbl_Currency INNER JOIN tbl_XRate ON tbl_Currency.Currency_ID = tbl_XRate.Currency_ID)
ON (qry_SALES.SalesDate = tbl_XRate.XDate) AND (qry_SALES.SalesCcy = tbl_Currency.Ccy)
ORDER BY qry_SALES.SalesDate;
How do I get transactions that are during a month to match up with the exchange rate table's last value?

Try this using the matching ultimo date of the month:
FROM
qry_SALES
INNER JOIN
(tbl_Currency
INNER JOIN tbl_XRate
ON tbl_Currency.Currency_ID = tbl_XRate.Currency_ID)
ON (DateSerial(Year(qry_SALES.SalesDate), Month(qry_SALES.SalesDate) + 1, 0) = tbl_XRate.XDate)
AND (qry_SALES.SalesCcy = tbl_Currency.Ccy)
or:
FROM
qry_SALES
INNER JOIN
(tbl_Currency
INNER JOIN tbl_XRate
ON tbl_Currency.Currency_ID = tbl_XRate.Currency_ID)
ON (qry_SALES.SalesCcy = tbl_Currency.Ccy)
WHERE
DateSerial(Year(qry_SALES.SalesDate), Month(qry_SALES.SalesDate) + 1, 0) = tbl_XRate.XDate

Related

Error getting the amount grouped by name and account number SQL Server

I have an issue on my SQL query. I tried doing two ways
With the first query I got the right amount but I lose some name descriptions
With the second I got every name descriptions but I got a lower amount.
Context: I want to get the revenue gotten between two dates.
I need the following columns from tables
Table reciboDet I need the columns CtaIngreso, ValorUnitReciboDet
Table CuentaIngreso_A the column nombrectaingreso, ctaingreso (only to create the join)
Table Recibo the columns FechaRecibo and ReciboAnulado
To get the right name descriptions I need to verify the receipt year that was in the table AvpgEnc, but when I do that a lose the amount.
First query
SELECT
ReciboDet.CtaIngreso
, SUM(ReciboDet.ValorUnitReciboDet) AS Total
, CuentaIngreso_A.NombreCtaIngreso
FROM
ReciboDet
INNER JOIN CuentaIngreso_A
ON ReciboDet.CtaIngreso = CuentaIngreso_A.CtaIngreso
WHERE
(ReciboDet.NumRecibo IN
(SELECT NumRecibo
FROM Recibo
WHERE (FechaRecibo BETWEEN '01/10/2020' AND '31/10/2020')
AND (ReciboAnulado = 0)
AND (CuentaIngreso_A.Anio = DATEPART(year, FechaRecibo))
)
)
GROUP BY
ReciboDet.CtaIngreso
, CuentaIngreso_A.NombreCtaIngreso
ORDER BY
CuentaIngreso_A.NombreCtaIngreso
Second query
SELECT
ReciboDet.CtaIngreso [cuenta],
sum(ReciboDet.ValorUnitReciboDet) [monto],
CuentaIngreso_A.NombreCtaIngreso [descripcion]
FROM
ReciboDet
inner join avpgenc
on ReciboDet.NumFactura = AvPgEnc.NumAvPg
inner join CuentaIngreso_A
on ReciboDet.CtaIngreso = CuentaIngreso_A.CtaIngreso
WHERE
(ReciboDet.NumRecibo IN
(SELECT NumRecibo
FROM Recibo
WHERE (FechaRecibo BETWEEN '01/10/2020' AND '31/10/2020')
AND (ReciboAnulado = 0)
)
AND (year(AvPgEnc.FechaVenceAvPg) = CuentaIngreso_A.Anio)
)
GROUP BY
ReciboDet.CtaIngreso
, CuentaIngreso_A.NombreCtaIngreso
ORDER BY
ReciboDet.CtaIngreso

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.

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

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

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.

Group on two columns and calculate net total SQL Query

I am finding it difficult to modify an existing SQL query to group records on two columns. Following is the query which retrieves records from multiple tables by joining:
SELECT
InM.invm_No AS DocNo,
InM.docs_DocCode,
D.doctyp_Desc AS DocType,
L.loc_Desc AS Site,
InM.sup_Code AS Supplier,
InD.invd_Qty,
InD.invd_Rate
FROM
[SI_InventoryMaster] InM
INNER JOIN
[SI_DocType] AS D ON InM.doctyp_Code = D.doctyp_Code
INNER JOIN
SI_Supplier S ON InM.sup_Code = S.sup_Code
INNER JOIN
[SI_InventoryDetail] AS InD ON InD.invm_No = InM.invm_No
AND InM.invm_verified = 1
AND InM.docs_DocCode = 'GRN'
AND MONTH (InM.invm_Date) = 12
AND YEAR(InM.invm_date) = 2013
INNER JOIN
SI_Location L ON InD.loc_code = L.loc_Code
ORDER BY
InM.invm_No
Which results the following:
I need to group records "by DocNo by Site" and find total amount for each site. Total amount will be last column in this resultset and it is net of product of InD.invd_Qty and InD.invd_Rate for each site.
For DocNo: 00000030, there are 4 records of CWS Store Site, so its total amount would be calculated as: 7684.999+7684.999+3000+3000=21369.998
In this particular example, modified query should return following resultset:
Please help.
Thanks.
Try grouping on all the columns associated with those two columns. Something like:
SELECT InM.invm_No AS DocNo, InM.docs_DocCode, D.doctyp_Desc AS DocType,
L.loc_Desc AS Site, InM.sup_Code AS Supplier,
sum(InD.invd_Qty),
sum(InD.invd_Rate)
FROM [SI_InventoryMaster] InM INNER JOIN
[SI_DocType] AS D
ON InM.doctyp_Code = D.doctyp_Code INNER JOIN
SI_Supplier S
ON InM.sup_Code = S.sup_Code INNER JOIN
[SI_InventoryDetail] AS InD
ON InD.invm_No = InM.invm_No AND
InM.invm_verified = 1 AND
InM.docs_DocCode = 'GRN' AND
MONTH (InM.invm_Date) = 12 AND
YEAR(InM.invm_date) = 2013 INNER JOIN
SI_Location L
ON InD.loc_code = L.loc_Code
GROUP BY InM.invm_No AS DocNo, InM.docs_DocCode, D.doctyp_Desc AS DocType,
L.loc_Desc AS Site, InM.sup_Code AS Supplier;