Select with WITH - sql-server

I am new in MySQL I have a db2 select and a would like to do this in MSsql and with WITH clause
db2
1 SQL.
SELECT
SQLUSER.TT_VALUTRAZ.SIFRA3,
SQLUSER.TT_VALUTRAZ.SIFVAL32,
SQLUSER.TT_VALUTRAZ.DATUM,
SQLUSER.TT_VALUTRAZ.RAZMERJE
FROM
SQLUSER.TT_VALUTRAZ
WHERE
(
(SQLUSER.TT_VALUTRAZ.DATUM >= '1.5.2007')
) ---> this go to DW.TEMP_PFPC_TT_VALUTRAZ
2 sql.
SELECT
'705' AS SIFRA3,
'891' AS SIFVAL32,
A.DATUM,
A.RAZMERJE AS RAZMERJE
FROM
DW.TEMP_PFPC_TT_VALUTRAZ A
WHERE
A.DATUM >= '1.5.2007' AND
A.SIFRA3 = '891' AND
A.SIFVAL32 = '978' AND
('705', '891', A.DATUM) NOT IN
(
SELECT
SIFRA3,
SIFVAL32,
DATUM
FROM
DW.TEMP_PFPC_TT_VALUTRAZ
WHERE
SIFRA3 = '705' AND
SIFVAL32 = '891'
)
now I like to join this two SQL statement and would like to use ons with clause and MSsql syntax

There are many ways of doing this. I only posted one way. There are some places that have been changed due to syntax issues. Let me know this answer if this answer is useful.
; WITH CTE_1 AS ( SELECT
SQLUSER.TT_VALUTRAZ.SIFRA3,
SQLUSER.TT_VALUTRAZ.SIFVAL32,
SQLUSER.TT_VALUTRAZ.DATUM,
SQLUSER.TT_VALUTRAZ.RAZMERJE
FROM
SQLUSER.TT_VALUTRAZ
WHERE
(
(SQLUSER.TT_VALUTRAZ.DATUM >= '1.5.2007')
) ---> this go to DW.TEMP_PFPC_TT_VALUTRAZ
)
, CTE_2 AS (
SELECT * FROM
(
SELECT
'705' AS SIFRA3,
'891' AS SIFVAL32,
A.DATUM,
A.RAZMERJE AS RAZMERJE
FROM
DW.TEMP_PFPC_TT_VALUTRAZ A
) AS B
WHERE
B.DATUM >= '1.5.2007' AND
B.SIFRA3 = 891 AND
B.SIFVAL32 = 978 AND
B.SIFRA3 NOT IN (705) --use of sub queries in where clause has been fixed.
AND B.SIFVAL32 NOT IN (891) --use of sub queries in where clause has been fixed.
AND B.DATUM NOT IN
(
SELECT
DATUM
FROM
DW.TEMP_PFPC_TT_VALUTRAZ
)
)
SELECT * FROM
CTE_1 AS [C]
INNER JOIN CTE_2 AS [CT]
ON [CTE_1]. [SIFRA3] = [CT].[SIFRA3]
AND [C]. [SIFVAL32] = [CT].[SIFVAL32]
AND [C].[DATUM] = [CT].[DATUM]
AND [C].[RAZMERJE] = [CT].[RAZMERJE]

Related

SQL Query running slow on the DB server

Execution plan is attached
SELECT a.*, k.UserPrivileges, k.Type
FROM NotifyInterests2 a, KUAF k
WHERE a.UserID = k.ID
AND EXISTS (SELECT ID FROM KUAF WHERE a.UserID = ID AND NOT Type IN (1, 2, 4))
AND (a.NodeID IN ( SELECT 0 UNION ALL ( SELECT DISTINCT( -1 * ID )
FROM KUAF WHERE Type = 5 ) UNION ALL ( SELECT DISTINCT AncestorID
FROM DTreeAncestors
WHERE Exists ( SELECT EventInt2 FROM LLEventQueue
WHERE EventHandlerID = 9001 AND EventSeqNo <=45075882 AND EventInt2 = DataID
UNION ALL SELECT EventInt2 * -1 FROM LLEventQueue
WHERE EventHandlerID = 9001
AND EventSeqNo <=45075882 AND EventInt2 = DataID ))))
that's quite the query =) Tip: try to 'group' the parts of your code for readability; it will make your life a 100 times easier; now while you're writing this and even more in the future when you're maintaining this =)
Some questions remain:
What do you call 'slow'?
How many records are present in each table?
How many records are returned by the query?
What are the indexes on the tables? (sp_helpindex)
Also, it probably would have been helpful to see the entire query plan, but one thing that stands out immediately is that KEAF doesn't seem to have clustered index. I presume it's thus also missing a Primary Key? As you have a field ID there I'd expect that this uniquely identifies each record? If so, add a PK to the table and check what effect this has on the entire query.
I've tried to re-arrange things a bit for readability and I ended up with below. I've gambled on some of the aliases as they are missing in the original query.
SELECT a.*, k.UserPrivileges, k.Type
FROM NotifyInterests2 a
JOIN KUAF k
ON k.ID = a.UserID
WHERE EXISTS ( SELECT kx.ID
FROM KUAF kx
WHERE kx.ID = a.UserID
AND NOT kx.Type IN (1, 2, 4) )
AND a.NodeID IN ( SELECT 0
UNION ALL
SELECT DISTINCT( -1 * k5.ID )
FROM KUAF k5
WHERE k5.Type = 5
UNION ALL
SELECT DISTINCT da.AncestorID
FROM DTreeAncestors da
WHERE EXISTS ( SELECT l1.EventInt2
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID
UNION ALL
SELECT l2.EventInt2 * -1
FROM LLEventQueue l2
WHERE l2.EventHandlerID = 9001
AND l2.EventSeqNo <= 45075882
AND l2.EventInt2 = da.DataID )
)
Some parts can be simplified I think.
This doesn't really make sense:
SELECT DISTINCT da.AncestorID
FROM DTreeAncestors da
WHERE EXISTS ( SELECT l1.EventInt2
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID
UNION ALL
SELECT l2.EventInt2 * -1
FROM LLEventQueue l2
WHERE l2.EventHandlerID = 9001
AND l2.EventSeqNo <= 45075882
AND l2.EventInt2 = da.DataID )
You're simply doing the same query twice in the WHERE EXISTS() part.
Also, as this part belongs to a WHERE IN (...) construction there's no real need for the DISTINCT. In fact, it's probably easier to convert it to a WHERE EXISTS() construction. Something like this:
AND ( a.NodeID = 0
OR EXISTS (SELECT *
FROM KUAF k5
WHERE k5.Type = 5
AND ( -1 * k5.ID ) = a.node_id)
OR EXISTS ( SELECT *
FROM DTreeAncestors da
WHERE da.AncestorID = a.NodeID
AND EXISTS ( SELECT *
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID )
)
Normally I'm no fan of OR but I think that in this case it might work.
So I end up with:
SELECT a.*, k.UserPrivileges, k.Type
FROM NotifyInterests2 a
JOIN KUAF k
ON k.ID = a.UserID
WHERE EXISTS ( SELECT kx.ID
FROM KUAF kx
WHERE a.UserID = kx.ID
AND NOT kx.Type IN (1, 2, 4) )
AND ( a.NodeID = 0
OR EXISTS (SELECT *
FROM KUAF k5
WHERE k5.Type = 5
AND ( -1 * k5.ID ) = a.node_id)
OR EXISTS ( SELECT *
FROM DTreeAncestors da
WHERE da.AncestorID = a.NodeID
AND EXISTS ( SELECT *
FROM LLEventQueue l
WHERE l.EventHandlerID = 9001
AND l.EventSeqNo <= 45075882
AND l.EventInt2 = da.DataID )
)
)
Give this a try and check the query plan. If it still is too slow we'll need to look at the indexes that are on the bespoken tables to see where we can optimize those.
You didn't mention if and which indexes exist in the table.
I would try creating the following indexes and see if there is any performance gain:
CREATE INDEX kuaf_idx_id_type ON KUAF (ID,Type);
CREATE INDEX kuaf_idx_type ON KUAF (Type);
CREATE INDEX lleventqueue_idx_eventha_eventin_dataid_eventse ON LLEventQueue (EventHandlerID,EventInt2,DataID,EventSeqNo);

Adding results from two queries

I'm using MS-SQL 2008 R2.
I have 2 Queries which are returning the required results.
But I need to add the two results from each queries to provide a final value [Enterprise Value]. I'm sure this is very straight forward but I'm going round in circles on this, have tried incorporating SUM which I think is the right approach?
Here is the full query as it currently stands:
declare #d1 datetime='2015-12-22'
(select
c.fs_perm_sec_id,
((c.p_price * s.p_com_shs_out)/1000) as [Enterprise Value]
from fp_v1.fp_basic_bd c
left join edm_v1.edm_security_entity_map e
on e.fs_perm_sec_id= c.fs_perm_sec_id
left join fp_v1.fp_basic_sho s
on s.fs_perm_sec_id = c.fs_perm_sec_id
and c.date=#d1
where s."date" =
(
select MAX(s2."date")
from fp_v1.fp_basic_sho s2
where s2.fs_perm_sec_id=c.fs_perm_sec_id
and s2."date" <= c."date"
)
and c."date"=#d1
and e.termination_date is null
and c.fs_perm_sec_id = 'GPHC8W-S-GB')
UNION ALL
select
ff.fs_perm_sec_id,
((FF_debt + ff_pfd_stk + ff_min_int_accum) - FF.ff_cash_st) as [Enterprise Value]
from ff_v2.ff_basic_af_v2 FF
where FF."date" =
( select MAX(FF2."date")
from ff_v2.ff_basic_af_v2 FF2
where FF2.fs_perm_sec_id=FF.fs_perm_sec_id
and FF.date <= FF2.date
)
and FF.fs_perm_sec_id =('GPHC8W-S-GB')
When inserting a "UNION ALL" between the two queries I get the following results:
fs_perm_sec_id Enterprise Value
GPHC8W-S-GB 9270.5204655
GPHC8W-S-GB 835
What I would like to achieve is a sum of the two values brought onto one row, i.e.:
fs_perm_sec_id Enterprise Value
GPHC8W-S-GB 10105.52
Thanks for your help.
Final SQL:
declare #d1 datetime='2015-12-23'
Select fs_perm_sec_id, SUM([Enterprise Value]) AS 'Enterprise Value'
from
(
(select
c.fs_perm_sec_id,
((c.p_price * s.p_com_shs_out)/1000) as [Enterprise Value]
from fp_v1.fp_basic_bd c
left join edm_v1.edm_security_entity_map e
on e.fs_perm_sec_id= c.fs_perm_sec_id
left join fp_v1.fp_basic_sho s
on s.fs_perm_sec_id = c.fs_perm_sec_id
and c.date=#d1
where s."date" =
(
select MAX(s2."date")
from fp_v1.fp_basic_sho s2
where s2.fs_perm_sec_id=c.fs_perm_sec_id
and s2."date" <= c."date"
)
and c."date"=#d1
and e.termination_date is null
and c.fs_perm_sec_id in ('FT9TC5-S-GB','GPHC8W-S-GB','R85KLC-S-US'))
UNION ALL
select
ff.fs_perm_sec_id,
((FF_debt + ff_pfd_stk + ff_min_int_accum) - FF.ff_cash_st) as [Enterprise Value]
from ff_v2.ff_basic_af_v2 FF
where FF."date" =
( select MAX(FF2."date")
from ff_v2.ff_basic_af_v2 FF2
where FF2.fs_perm_sec_id=FF.fs_perm_sec_id
and FF.date <= FF2.date
)
and FF.fs_perm_sec_id in ('FT9TC5-S-GB','GPHC8W-S-GB','R85KLC-S-US')) t
group by t.fs_perm_sec_id
just use the Derived Table and Group by
Select fs_perm_sec_id,
SUM(Enterprise Value) EnterpriseValue
from (**your whole code**)
GROUP BY fs_perm_sec_id
use group by
How to use group by with union in t-sql
SELECT id,sum(*)
FROM ( SELECT id,
time
FROM dbo.a
UNION
SELECT id,
time
FROM dbo.b
)
GROUP BY id
DECLARE
#d1 DATE = '20151222'
, #fs_perm_sec_id VARCHAR(100) = 'GPHC8W-S-GB'
SELECT #fs_perm_sec_id, SUM([Enterprise Value])
FROM (
SELECT [Enterprise Value]
FROM (
SELECT
c.fs_perm_sec_id
, (c.p_price * s.p_com_shs_out) / 1000 AS [Enterprise Value]
, RowNum = ROW_NUMBER() OVER (ORDER BY s.[date] DESC)
from fp_v1.fp_basic_bd c
join fp_v1.fp_basic_sho s on s.fs_perm_sec_id = c.fs_perm_sec_id
left join edm_v1.edm_security_entity_map e on e.fs_perm_sec_id= c.fs_perm_sec_id
where c.[date] = #d1
and e.termination_date is null
and c.fs_perm_sec_id = #fs_perm_sec_id
) t
WHERE t.RowNum = 1
UNION ALL
SELECT FF_debt + ff_pfd_stk + ff_min_int_accum - ff_cash_st
FROM (
SELECT
ff.fs_perm_sec_id
, FF_debt
, ff_pfd_stk
, ff_min_int_accum
, FF.ff_cash_st
, RowNum = ROW_NUMBER() OVER (ORDER BY FF.[date] DESC)
FROM ff_v2.ff_basic_af_v2 FF
WHERE FF.[date] =
AND FF.fs_perm_sec_id = #fs_perm_sec_id
) t
WHERE t.RowNum = 2
) t

In plpgsql (of PostgreSQL), can a CTE be preserved to an outer loop?

(Edited from the original).
In plpgsql, (PostgreSQL 9.2), I have a function defined as:
CREATE OR REPLACE FUNCTION test (patient_recid integer, tencounter timestamp without time zone)
RETURNS SETOF view_dx AS
$BODY$
#variable_conflict use_column
DECLARE
r view_dx%rowtype;
BEGIN
FOR r IN
With person AS (
select ....
)
, alldx AS (
select ....
)
............
select ... from first cte
union
select ... from second cte
union
etc., etc.,
LOOP
r.tposted = ( .
With person AS (
... SAME AS ABOVE,
alldx AS (
... SAME AS ABOVE,
)
select max(b.tposted)
from alldx b
where r.cicd9 = b.code and r.cdesc = b.cdesc);
r.treated = (
With person AS (
........SAME AS ABOVE )
, alldx AS (
........SAME AS ABOVE
)
select ...);
r.resolved = (
With person AS (
select p.chart_recid as recid
from patients p
where p.recid = patient_recid
)
...etc, etc,
RETURN NEXT r;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION test(integer, timestamp without time zone)
OWNER TO postgres;
Edit: Essentially, I have multiple cte's defined which work well in the "For r IN" section of code with multiple unions, but when executing the LOOP...END LOOP section, each CTE needs to be redefined with each SELECT statement. Is there a good way to avoid multiple definitions of the same CTE?
Or is there a better (i.e., faster) way of doing this.
All suggestions are most welcome and appreciated.
TIA
[this is not an answer (too little information, too large program), but a hint for rewriting the stacked CTE.]
The members of the union all appear to be based on select b.* from alldx b, all with a few different extra conditions, mostly based on the existance of other tuples within the same CTE. My suggestion is to unify these, replacing them by boolean flags, as in:
WITH person AS (
SELECT p.chart_recid as recid
FROM patients p
WHERE p.recid = patient_recid
)
, alldx AS (
SELECT d.tposted, d.treated, d.resolved, d.recid as dx_recid, d.pmh, d.icd9_recid
, i.code, i.cdesc, i.chronic
FROM dx d
JOIN icd9 i ON d.icd9_recid = i.recid
JOIN person p ON d.chart_recid = p.recid
WHERE d.tposted::date <= tencounter::date
)
SELECT uni.tposted, uni.treated, uni.resolved, uni.dx_recid, uni.pmh, uni.icd9_recid
, uni.code, uni.cdesc, uni.chronic
, (uni.tposted::date = tencounter::date
) AS is_dx_at_encounter -- bitfield
, EXISTS ( -- a record from a more recent date has resolved this problem.
SELECT 1
FROM alldx x
WHERE x.resolved = true
AND uni.code = x.code AND uni.cdesc = x.cdesc AND uni.tposted = x.tposted
AND x.tposted >= uni.tposted
) AS dx_resolved -- bitfield
, EXISTS ( -- a record from a more recent date has resolved this problem.
SELECT 1
FROM alldx x
WHERE x.resolved = false
AND uni.code = x.code AND uni.cdesc = x.cdesc AND uni.tposted = x.tposted
AND x.tposted > uni.tposted
) AS dx_recurred -- bitfield
, EXISTS ( SELECT * from alldx x where x.chronic = true
AND uni.code = x.code AND uni.cdesc = x.cdesc
) AS dx_chronic -- bitfield
-- etcetera
FROM alldx uni
;
The person CTE could probably be incorporated, too.
and maybe you don't even need the final loop
but you'll have to find out which combination(s) of the resulting bitfields will be needed.
the UNION (without ALL) in the original is a terrible beast: it collects all the results from the union parts, but has to remove duplicates. This will probably introduce a sort-step, since CTE-references tend to hide their key fields or implied ordering from the calling query.
As far as I can tell, CTE's defined before the LOOP do not transfer to the LOOP itself. However, a temporary table can be defined in the BEGIN block which is available in the LOOP block. The following solution runs 50 times faster then my original code. Anybody have a better approach?
CREATE OR REPLACE FUNCTION test2 (patient_recid integer, tencounter timestamp without time zone)
RETURNS SETOF view_dx AS
$BODY$
#variable_conflict use_column
DECLARE
r view_dx%rowtype;
BEGIN
-- create table can only be created in the BEGIN block
Create temp table all_dx ON COMMIT DROP AS
With person AS (
select p.chart_recid as recid
from patients p
where p.recid = patient_recid
)
, alldx AS (
select d.tposted, d.treated, d.resolved, d.recid as dx_recid, d.pmh, d.icd9_recid, i.code, i.cdesc, i.chronic
from dx d
join icd9 i on (d.icd9_recid = i.recid)
join person p on (d.chart_recid = p.recid)
where d.tposted::date <= tencounter::date
)
select * from alldx order by tposted desc;
-- will loop through all the records produced by the unions and assign tposted, pmh, chronic, etc...
FOR r IN
With
dx_at_encounter AS ( -- get all diagnosis at time of encounter
select code, cdesc from all_dx a
where a.tposted::date = tencounter::date
)
, dx_resolved AS ( -- get most recent date of every resolved problem.
select b.* from all_dx b
join (
select a.code, a.cdesc , max(tposted) as tposted
from all_dx a
where a.resolved = true
group by code,cdesc) j
on (b.code = j.code and b.cdesc = j.cdesc and b.tposted = j.tposted)
)
, never_resolved AS ( -- get all problems that have never been resolved before time of encounter.
-- "not exists" is applied to each select output row AFTER the output row b.* is formed.
select b.code, b.cdesc from all_dx b
where not exists
(select 1
from dx_resolved d
where b.code = d.code and b.cdesc = d.cdesc)
)
, recurrent AS ( -- get all recurrent problems. (Problems that are now current after being resolved).
select b.code, b.cdesc
from all_dx b
join dx_resolved r on (b.cdesc = r.cdesc and b.tposted::date > r.tposted::date )
where (b.resolved is null or b.resolved = false)
)
, chronic_dx AS (
select b.code, b.cdesc
from all_dx b
where b.chronic = true
)
-- all diagnosis at time of encounter
select a.code,
a.cdesc
from dx_at_encounter a
union
-- all recurrent problems
select
a.code,
a.cdesc
from recurrent a
union
-- all problems that have never been resolved
select
a.code,
a.cdesc
from never_resolved a
union
--all chonic problems
select
a.code,
a.cdesc
from chronic_dx a
-- LOOP goes to END LOOP which returns back to LOOP to process each of the result records from the unions.
LOOP
r.tposted = ( -- get most recent useage of a diagnosis.
select max(b.tposted)
from all_dx b
where r.cicd9 = b.code and r.cdesc = b.cdesc);
r.treated = (
select b.treated from all_dx b
where b.tposted = r.tposted and b.code = r.cicd9 and b.cdesc = r.cdesc);
r.resolved = (
select b.resolved from all_dx b
where b.tposted = r.tposted and b.code = r.cicd9 and b.cdesc = r.cdesc);
r.pmh = (
select distinct true
from all_dx b
where
b.pmh = true and
b.code = r.cicd9 and
b.cdesc = r.cdesc );
r.chronic = (
select distinct true
from all_dx b
where
b.chronic = true and
b.code = r.cicd9 and
b.cdesc = r.cdesc);
RETURN NEXT r; -- return current row of SELECT
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION test2(integer, timestamp without time zone)
OWNER TO postgres;

how to convert the below subquery into joins using one update statement

Below is a complete query I have and the ultimate aim is to update the claim table. But it should be only one statement without any subquery, only joins are allowed because I am going to run this in an appliance which won't support subquery:
DECLARE #DecWdrwn as TABLE(CtryId smallint, CmId int, DecWdrwnDt int);
WITH s AS
(
SELECT
Ctryid,CmId,Dt,
ISNULL((
SELECT max(CmHistDtTmId)
FROM ClaimHistory l
WHERE St = 3
AND l.Ctryid = c.Ctryid
AND l.CmId = c.CmId)
, 0) MaxDec,
ISNULL((
SELECT max(CmHistDtTmId)
FROM ClaimHistory l
WHERE St = 7
AND l.Ctryid = c.Ctryid
AND l.CmId = c.CmId)
, 0) MaxSet
FROM
ClaimHistory c
WHERE
St =3
)
INSERT INTO #DecWdrwn
SELECT CtryId, CmId, Max(Dt) DecDt
FROM s
WHERE MaxSet > MaxDec
GROUP BY CtryId,CmId
Your response is much appreciated...
UPDATE Claims
SET CmDclnWdwnDt = (
SELECT DecWdrwnDt
FROM #DecWdrwn d
WHERE d.CmId = Claims.CmId
AND d.CtryId = Claims.CtryId
)
WHERE EXISTS (
SELECT *
FROM #DecWdrwn d
WHERE d.CmId = Claims.CmId
AND d.CtryId = Claims.CtryId
)
Please try INNER JOIN Update:
UPDATE a
SET a.CmDclnWdwnDt = b.DecWdrwnDt
FROM Claims a, #DecWdrwn b
WHERE a.CmId = b.CmId AND
a.CtryId =b.CtryId

Convert From Access Query to SQL Server

I'm trying to convert a report query from Access to SQL SERVER 2008. Using the same database but i can't get the same results. not even close. The Access query is like this:
SELECT Sum(INPUT_ItemSaleLines.TaxExclusiveTotal) AS TotalexTax,([TotalexTax])- Sum( Nz([SumOfTaxExclusiveAmount])+ Nz([CostOfGoodsSoldAmount])+ Nz
(
Nz
( IIf
( Left([Input_Items.ItemNumber],5)='31-63',136*[Quantity]/1000,
IIf(Left([Input_Items.ItemNumber],6)='34S-63',200*[Quantity]/1000)
)
)+ Nz
( IIf
( Left([Input_Items.ItemNumber],5)='34-63',250*[Quantity]/1000,
IIf(Left([Input_Items.ItemNumber],6)='26-63',250*[Quantity]/1000)
)
)
)
) AS Margin,
INPUT_Cards_1.Name AS SalesPerson, INPUT_Sales.SalesPersonID,
INPUT_Sales.InvoiceStatusID, INPUT_Cards.Name, INPUT_Items.ItemName,
Sum(INPUT_ItemSaleLines.Quantity) AS TotalQty,
Sum(INPUT_ItemSaleLines.CostOfGoodsSoldAmount) AS TotalCOGS,
Count(INPUT_Sales.SaleID) AS [Number of Sales],
Sum(qryShippingTotalexGST.SumOfTaxExclusiveAmount) AS ShippingTotal
FROM
( qryShippingTotalexGST RIGHT JOIN
(
(
(
INPUT_Items INNER JOIN INPUT_ItemSaleLines
ON INPUT_Items.ItemID = INPUT_ItemSaleLines.ItemID
) INNER JOIN INPUT_Sales ON INPUT_ItemSaleLines.SaleID = INPUT_Sales.SaleID
) INNER JOIN INPUT_Cards ON INPUT_Sales.CardRecordID = INPUT_Cards.CardRecordID
) ON qryShippingTotalexGST.JobID = INPUT_ItemSaleLines.JobID
) LEFT JOIN INPUT_Cards AS INPUT_Cards_1 ON INPUT_Sales.SalesPersonID = INPUT_Cards_1.CardRecordID
WHERE
(((INPUT_Sales.Date) Between [Forms]![MenuReports]![StartDate] And [Forms]![MenuReports]![EndDate]))
GROUP BY INPUT_Items.ItemNumber,
INPUT_Cards_1.Name, INPUT_Sales.SalesPersonID, INPUT_Sales.InvoiceStatusID,
INPUT_Cards.Name, INPUT_Items.ItemName
HAVING
(((INPUT_Sales.InvoiceStatusID)<>"OR"));
Then the SQL Server script that i write like this:
SELECT MYOBItems.ItemName, MYOBCards.Name AS SalesPerson, MYOBCards1.Name,
SUM(MYOBsalesLines.Qty) AS TotalQty,
SUM(MYOBsalesLines.CostOfGoodsSoldAmount) AS TotalCOGS,
COUNT(MYOBSales.SaleID) AS NumberOfSales,
SUM(MYOBsalesLines.TaxExclusiveAmount) AS TotalexTax,
SUM(cast(MYOBJobsShippingTotals.TaxExclusiveAmount AS Decimal(18,2))) AS ShippingTotal,
(SUM(MYOBsalesLines.TaxExclusiveAmount)) - SUM
(
COALESCE(cast(MYOBJobsShippingTotals.TaxExclusiveAmount AS Decimal(18,2)),0)+ COALESCE(MYOBsalesLines.CostOfGoodsSoldAmount,0)+ COALESCE
(
COALESCE
(
CASE
WHEN LEFT(MYOBItems.ItemNumber,5) = '31-63' THEN (136*MYOBsalesLines.Qty/1000)
WHEN LEFT(MYOBItems.ItemNumber,6) = '34S-63' THEN (200*MYOBsalesLines.Qty/1000)
ELSE 0
END, 0
)+ COALESCE
(
CASE
WHEN LEFT(MYOBItems.ItemNumber,5) = '34-63' THEN (250*MYOBsalesLines.Qty/1000)
WHEN LEFT(MYOBItems.ItemNumber,6) = '26-63' THEN (250*MYOBsalesLines.Qty/1000)
ELSE 0
END , 0
), 0
)
)AS Margin
, MYOBSales.InvoiceStatusID FROM
( MYOBJobsShippingTotals RIGHT JOIN
(
(
(
MYOBItems INNER JOIN MYOBsalesLines
ON MYOBItems.ItemID = MYOBsalesLines.ItemID
) INNER JOIN MYOBSales ON MYOBsalesLines.SaleID = MYOBSales.SaleID
AND MYOBSales.ElevateCompanyID = MYOBsalesLines.ElevateCompanyID
) INNER JOIN MYOBCards AS MYOBCards1 ON MYOBSales.CardRecordID = MYOBCards1.CardRecordID
AND MYOBsalesLines.ElevateCompanyID = MYOBCards1.ElevateCompanyID
AND MYOBSales.ElevateCompanyID = MYOBCards1.ElevateCompanyID
) ON MYOBJobsShippingTotals.JobID = MYOBsalesLines.JobID
) LEFT JOIN MYOBCards ON MYOBSales.SalesPersonID = MYOBCards.CardRecordID
GROUP BY MYOBItems.ItemName, MYOBCards.Name,
MYOBCards1.Name, MYOBSales.InvoiceStatusID
I suspect there was something wrong with the joined tables but not sure how to fix it.
Is there any mistake in my SQL Server script that is not relevant with the Access syntax?
Thank for the help in advance. and sorry for my long scripts.
Your SQL server query is missing the WHERE and HAVING clauses of the MS Access query, it's GROUP BY clause doesn't have the same number or order of columns as the MS Access query, and has additional JOIN criteria that wasn't in the MS Access query.
A more faithful conversion would look like this:
SELECT SUM(MYOBsalesLines.TaxExclusiveAmount) AS TotalexTax
, SUM(MYOBsalesLines.TaxExclusiveAmount)
- SUM
(
COALESCE(cast(MYOBJobsShippingTotals.TaxExclusiveAmount AS Decimal(18,2)), 0)
+ COALESCE(MYOBsalesLines.CostOfGoodsSoldAmount,0)
+ COALESCE
(
COALESCE
(
CASE
WHEN LEFT(MYOBItems.ItemNumber,5) = '31-63' THEN (136*MYOBsalesLines.Qty/1000)
WHEN LEFT(MYOBItems.ItemNumber,6) = '34S-63' THEN (200*MYOBsalesLines.Qty/1000)
ELSE 0
END
, 0
)
+ COALESCE
(
CASE
WHEN LEFT(MYOBItems.ItemNumber,5) = '34-63' THEN (250*MYOBsalesLines.Qty/1000)
WHEN LEFT(MYOBItems.ItemNumber,6) = '26-63' THEN (250*MYOBsalesLines.Qty/1000)
ELSE 0
END
, 0
)
, 0
)
)
AS Margin
, MYOBCards1.Name AS SalesPerson
, MYOBSales.SalesPersonID
, MYOBSales.InvoiceStatusID
, MYOBCards.Name
, MYOBItems.ItemName
, SUM(MYOBsalesLines.Qty) AS TotalQty
, SUM(MYOBsalesLines.CostOfGoodsSoldAmount) AS TotalCOGS
, COUNT(MYOBSales.SaleID) AS NumberOfSales
, SUM(cast(MYOBJobsShippingTotals.TaxExclusiveAmount AS Decimal(18,2))) AS ShippingTotal
FROM
(
MYOBJobsShippingTotals RIGHT JOIN
(
(
(
MYOBItems INNER JOIN MYOBsalesLines
ON MYOBItems.ItemID = MYOBsalesLines.ItemID
) INNER JOIN MYOBSales ON MYOBsalesLines.SaleID = MYOBSales.SaleID
) INNER JOIN MYOBCards ON MYOBSales.CardRecordID = MYOBCards.CardRecordID
) ON MYOBJobsShippingTotals.JobID = MYOBsalesLines.JobID
) LEFT JOIN MYOBCards AS MYOBCards1 ON MYOBSales.SalesPersonID = MYOBCards1.CardRecordID
WHERE MYOBSales.Date BETWEEN ? AND ?
GROUP BY MYOBItems.ItemNumber
, MYOBCards1.Name
, MYOBSales.SalesPersonID
, MYOBSales.InvoiceStatusID
, MYOBCards.Name
, MYOBItems.ItemName
HAVING MYOBSales.InvoiceStatusID <> 'OR'
Where the two question marks are your [Forms]![MenuReports]![StartDate] and [Forms]![MenuReports]![EndDate] values.

Resources