How to Select NOT IN Value (Formula Crystal Reports) - sql

I have this query in SQL server:
select * from ARInvoices ar
left join ARInvoiceDetails det on ar.InvoiceID = det.InvoiceID
where ar.InvoiceID not in (select InvoiceID from CashReceiptInvoices )
and det.SubmitTo = 1 and VoucherStatus = 0 and det.TransactionType = 1
I would like to have it thru a Formula in Crystal Reports XI but i'm having a hard time with the not in. I used <> but the results are coming empty.

I don't know crystal reports at all, but if it's only the NOT IN you're having trouble with, but your LEFT JOIN works fine, then you could just add another LEFT JOIN:
select *
from ARInvoices ar
left join ARInvoiceDetails det on ar.InvoiceID = det.InvoiceID
left join CashReceiptInvoices cri on ar.InvoiceID = cri.InvoiceID
where cri.InvoiceID IS NULL
and det.SubmitTo = 1
and VoucherStatus = 0
and det.TransactionType = 1

You could eliminate the NOT IN by using an "anti-join" (a LEFT JOIN with a constraint where the column in the table to which you are joining IS NULL):
select * from ARInvoices ar
left join ARInvoiceDetails det on ar.InvoiceID = det.InvoiceID
left join CashReceiptInvoices cri on ar.InvoiceID = cri.InvoiceID -- new JOIN
where cri.InvoiceID is null -- no match
and det.SubmitTo = 1 and VoucherStatus = 0 and det.TransactionType = 1

Related

Big Query : LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join

I am writing an equivalent logic in BQ as in my source system. In source SQL server side it is working fine. But in Big query it is failing with the OR condition in the last left outer join condition. If I am moving the OR condition in the where clause it is giving wrong count. Need help to fix this issue. How can I re write the below query ?
SELECT count(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON (DIM.diSet = PRO.diSet)
INNER JOIN DQConfig CFG
ON (CFG.ConSet = PRO.ConSet)
LEFT OUTER JOIN AgSt CCT
ON (CCT.StSet = PRO.StSet)
INNER JOIN stprof SummPRO
ON (SummPRO.diSet = DIM.SummdiSet AND
SummPRO.dIntervalStart = PRO.dIntervalStart AND
SummPRO.SiteId = PRO.SiteId AND
SummPRO.nDuration = PRO.nDuration)
LEFT OUTER JOIN AgSt SummCCT
ON (SummCCT.StSet = SummPRO.StSet)
LEFT OUTER JOIN AgentStatus SummSTS
ON (
SummSTS.StSet = SummPRO.StSet
OR
SummSTS.StSet = PRO.StSet)
WHERE DIM.cType = 'A'
You can replace LEFT JOIN with CROSS JOIN and move condition from ON clause to WHERE clause as in below example
#standardSQL
SELECT COUNT(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON DIM.diSet = PRO.diSet
INNER JOIN DQConfig CFG
ON CFG.ConSet = PRO.ConSet
LEFT OUTER JOIN AgSt CCT
ON CCT.StSet = PRO.StSet
INNER JOIN stprof SummPRO
ON SummPRO.diSet = DIM.SummdiSet
AND SummPRO.dIntervalStart = PRO.dIntervalStart
AND SummPRO.SiteId = PRO.SiteId
AND SummPRO.nDuration = PRO.nDuration
LEFT OUTER JOIN AgSt SummCCT
ON SummCCT.StSet = SummPRO.StSet
CROSS JOIN AgentStatus SummSTS
WHERE DIM.cType = 'A'
AND (
SummSTS.StSet = SummPRO.StSet
OR SummSTS.StSet = PRO.StSet
)

Single-row subquery returns more than one row - Case statement

My following code returns the error stated in the title, however the error does not show when the case statement is ran by itself.
I've tried to dismantle the case statement, however this isn't my query but IS being used elsewhere, i'm wondering how they manage to get it to return rows in its current state.
SELECT DISTINCT V55."INPUTSPECNAME",
V55."FKMATERIAL",
V55."INPUTQUANTITYVALUE",
B.ABBREVIATION,
(CASE
WHEN z.COST IS NULL
THEN (SELECT DISTINCT (CASE
WHEN MatOut_D.PERVALUEQUANTITY > 0 THEN
ROUND(MatOut_D.PRICE /
MatOut_D.PERVALUEQUANTITY /
10 /
MatOut_E.USDCONVERSIONFACTOR *
C.USDCONVERSIONFACTOR, 5)
ELSE 0
END)
FROM V55_FORMULATIONJOINMATOUTPUT MatOut_B,
V55_FORMULATIONINPUTOUTPUT MatOut_C,
THEORETICALCOSTS MatOut_D,
COMMONCURRENCIES MatOut_E,
UOMML MatOut_F
WHERE MatOut_B.FKREFERENCEDMATERIAL = V55.FKMATERIAL
AND MatOut_B.FKOWNER = MatOut_C.FKOWNER
AND MatOut_C.FORMULATIONOUTPUTPKID = MatOut_D.FKPARENT
AND MatOut_D.FKCURRENCY = MatOut_E.PKID
AND MatOut_D.FKPERVALUEUOM = MatOut_F.FKUOM
AND MatOut_F.LANGID = 0)
ELSE ROUND(z.COST*100/D.USDCONVERSIONFACTOR*C.USDCONVERSIONFACTOR,5)
END) AS COST_100G
FROM V55_FORMULATIONINPUTOUTPUT V55
INNER JOIN UOM A
on V55.FKINPUTUOM = A.PKID
INNER JOIN UOMML B
on a.pkid = B.FKUOM
INNER JOIN DWBSpecificationRoots dwbRoot
on dwbRoot.fkOwner = V55.FKOWNER
INNER JOIN dwbSpecifications dwbSpec
ON dwbSpec.fkWorkingVersionParent = dwbRoot.pkid
LEFT OUTER JOIN specLegacySpecJoin y
on dwbSpec.fkdisplayedlegacyprofile = y.fklegacyprofileid
and y.fkspecid = V55.fkMaterial
LEFT OUTER join COSTITEMS z
on z.equivalent = y.equivalent
and z.fklegacyprofile = dwbSpec.fkdisplayedlegacyprofile
and z.FKSCRMENTITY = dwbSpec.FKSCRMSUPPLIERBASE
and z.COSTTYPE = dwbSpec.COSTTYPE
LEFT OUTER JOIN COMMONCURRENCIES C
ON C.PKID = dwbSpec.FKCURRENCY
LEFT OUTER JOIN COMMONCURRENCIES D
ON D.PKID = Z.FKCURRENCY
The problem is that the subquery in your CASE statement is returning multiple rows in some situations and as has been stated in the question's comments that's a no-no.
I suggest that you pull the subquery out of the CASE statement and make it a Common Table Expression, then join it into the query as you would any other table:
WITH cteSubexpr AS (SELECT DISTINCT MatOut_B.FKREFERENCEDMATERIAL,
(CASE
WHEN MatOut_D.PERVALUEQUANTITY > 0 THEN
ROUND(MatOut_D.PRICE /
MatOut_D.PERVALUEQUANTITY /
10 /
MatOut_E.USDCONVERSIONFACTOR *
C.USDCONVERSIONFACTOR, 5)
ELSE 0
END) AS CALC_QTY
FROM V55_FORMULATIONJOINMATOUTPUT MatOut_B
INNER JOIN V55_FORMULATIONINPUTOUTPUT MatOut_C
ON MatOut_C.FKOWNER = MatOut_B.FKOWNER
INNER JOIN THEORETICALCOSTS MatOut_D
ON MatOut_D.FKPARENT = MatOut_C.FORMULATIONOUTPUTPKID
INNER JOIN COMMONCURRENCIES MatOut_E
ON MatOut_E.PKID = MatOut_D.FKCURRENCY
INNER JOIN UOMML MatOut_F
ON MatOut_F.FKUOM = MatOut_D.FKPERVALUEUOM
WHERE MatOut_F.LANGID = 0)
SELECT DISTINCT V55.INPUTSPECNAME,
V55.FKMATERIAL,
V55.INPUTQUANTITYVALUE,
B.ABBREVIATION,
(CASE
WHEN z.COST IS NULL
THEN cs.CALC_QTY
ELSE ROUND(z.COST * 100 / D.USDCONVERSIONFACTOR * C.USDCONVERSIONFACTOR, 5)
END) AS COST_100G
FROM V55_FORMULATIONINPUTOUTPUT V55
INNER JOIN cteSubexpr cs
ON cs.FKREFERENCEDMATERIAL = V55.FKMATERIAL
INNER JOIN UOM A
on V55.FKINPUTUOM = A.PKID
INNER JOIN UOMML B
on a.pkid = B.FKUOM
INNER JOIN DWBSpecificationRoots dwbRoot
on dwbRoot.fkOwner = V55.FKOWNER
INNER JOIN dwbSpecifications dwbSpec
ON dwbSpec.fkWorkingVersionParent = dwbRoot.pkid
LEFT OUTER JOIN specLegacySpecJoin y
on dwbSpec.fkdisplayedlegacyprofile = y.fklegacyprofileid
and y.fkspecid = V55.fkMaterial
LEFT OUTER join COSTITEMS z
on z.equivalent = y.equivalent
and z.fklegacyprofile = dwbSpec.fkdisplayedlegacyprofile
and z.FKSCRMENTITY = dwbSpec.FKSCRMSUPPLIERBASE
and z.COSTTYPE = dwbSpec.COSTTYPE
LEFT OUTER JOIN COMMONCURRENCIES C
ON C.PKID = dwbSpec.FKCURRENCY
LEFT OUTER JOIN COMMONCURRENCIES D
ON D.PKID = Z.FKCURRENCY
Best of luck.

How to include a JOIN after the WHERE?

I need to execute a statement that follows a given Prefix.
We use a certain program, it features a 'Search Folder'. Into the Search folder, I can define an SQL query. The Folder has a built-in part of the query, which I can not modify.
The built-in part is:
Prefix Artikelfilter: SELECT * FROM CMKAT.ART WHERE 1=1 AND
Now I would like to perform the following search query:
select * from CMKAT.ART
join CMKAT.AEZ on art.artKEYI = aez.aezartkeyi
join pro on pro.prokeyi = aez.aezprokeyi
left outer join psz on pro.prokeyi = psz.pszprokeyi
WHERE psz.pszprokeyi is null
AND pro.proetykeyi = 1;
Of course, the 'SELECT *...' part is redundant, but how can I get the query to work? The JOINs are after the WHERE.
I know the developers solved this issues by creating Views, and making the selection from the view, not directly in the query.
Edit:
Exception: JdbcAccess.execute failed (ORA-00904: "KVTBEZC": ungültige ID
).
SQL:
<prefix>
SELECT /* filter art */ artkeyi, artkavkeyi, artvnrs FROM art JOIN
kav ON art.artkavkeyi = kav.kavkeyi JOIN kvt ON kav.kavkvtkeyi =
kvt.kvtkeyi JOIN kat ON kav.kavkatkeyi = kat.katkeyi WHERE
(artkavkeyi IN (587, 3075, 7, 8, 592)) AND
</prefix>
1 = 0 union all select *
from cmkat.art join cmkat.aez on art.artkeyi = aez.aezartkeyi join
pro on pro.prokeyi = aez.aezprokeyi left join psz on pro.prokeyi =
psz.pszprokeyi where psz.pszprokeyi is null and pro.proetykeyi = 1
AND katkeyi = 4 AND (katspes IN (0, 3, 1, 2))/* join-dummy */ ORDER BY
artkeyi, kvtbezc (DATABASE_EXECUTE_FAILED)
I guess you need right query like this:
If exists (SELECT 1 FROM CMKAT.ART WHERE 1=1)
Begin
(
Select *
From CMKAT.ART
Inner join CMKAT.AEZ on art.artKEYI = aez.aezartkeyi
Inner join pro on pro.prokeyi = aez.aezprokeyi
Left Outer join psz on pro.prokeyi = psz.pszprokeyi
WHERE psz.pszprokeyi is null AND pro.proetykeyi = 1;
)
END
I'd construct the SQL this way:
SELECT *
FROM CMKAT.ART
WHERE 1=1 AND EXISTS (Select 1
From CMKAT.AEZ, pro
left outer join psz on pro.prokeyi = psz.pszprokeyi
Where aez.aezartkeyi = art.artKEYI and pro.prokeyi = aez.aezprokeyi and psz.pszprokeyi is null AND pro.proetykeyi = 1
);
I don't know if your tool allows such construction, but you could cheat it using union all:
select * from cmkat.art where 1 = 1 and 1 = 0
union all
select cmkat.art.*
from cmkat.art
join cmkat.aez on art.artkeyi = aez.aezartkeyi
join pro on pro.prokeyi = aez.aezprokeyi
left join psz on pro.prokeyi = psz.pszprokeyi
where psz.pszprokeyi is null and pro.proetykeyi = 1;
First line removes data of original query because of 1 = 0 condition so we get only data from second part of union.
Unfortunately you can obtain only columns of art table because your tool does not allow to change selected data. But you can change it selecting some columns from joined tables instead of art columns.

summation in sql

I have a query result tabletable of result i would like to sum the bill amount such that it returns one row with a distinct account ,balance,sum billed amount fPreviousReading,
fCurrentReading,
fConsumption .
result should be
1.account 11074
2.balance269.49
3.sumbilledamount 520.48
4. fPreviousReading 574
5 fCurrentReading 612
6 fConsumption 38
Thanks
query
select
Ten.Account,
ten.DCBalance AS Balance,
SUM(T.fInclusiveAmount)AS BilledAmount,
MRD.fPreviousReading,
MRD.fCurrentReading ,
MRD.fConsumption ,
T.cDescription
from _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join _mtblPropertyPortions PP ON PP.idPropertyPortions = T.iPortionID
left join _mtblPropertyPortionServices PPS ON PPS.idPropertyPortionServices = T.iPropertyPortionServiceID
left join _mtblCategories Cat ON Cat.idCategory = PP.iPortionUsageID
left join _mtblServices S ON PPS.iPortionServiceID = S.idService
left join _mtblServiceGroups SG ON S.iServiceGroupID = SG.idServiceGroup
left join _mtblRateTariffs RT ON RT.idRateTariffs = PPS.iServiceRateTariffID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join _mtblMeters M ON PPS.iPropertyPortionMeterID = M.idMeter
left join _mtblWalkDetails WD ON WD.iWalkMeterID = PPS.iPropertyPortionMeterID
left join _mtblWalks W ON WD.iWalkID = W.idWalk
left join Client Own ON P.iPropertyOwnerID = Own.DCLink
left outer join _mtblRegions R on R.idRegions = P.iPropertyRegionID
left outer join _mtblSubRegions SR on SR.idSubRegions = P.iPropertySubRegionID
left outer join _mtblAreas A on A.idAreas = P.iPropertyAreaID
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
Where
oWN.Account='11074'
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance,MRD.fPreviousReading, MRD.fCurrentReading, MRD.fConsumption, T.cDescription
As I don't know your data, there is a possibility I wrote you a code that would return some double rows. But that is a problem you can easily handle.
Try it, nevertheless:
SELECT t1.Account,
t1.Balance,
t1.BilledAmount,
t1.fPreviousReading,
t1.fCurrentReading,
t1.fConsumption,
t2.cDescription
FROM (SELECT Ten.Account,
ten.DCBalance AS Balance,
SUM (T.fInclusiveAmount) AS BilledAmount,
SUM (MRD.fPreviousReading) AS fPreviousReading,
SUM (MRD.fCurrentReading) AS fCurrentReading,
SUM (MRD.fConsumption) AS fConsumption
FROM _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join Client Own ON P.iPropertyOwnerID = Own.DCLink AND oWN.Account='11074'
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance) t1
JOIN (SELECT T.cDescription,
Ten.Account,
ten.DCBalance
FROM _mtblTransactions T
left join Client Ten ON T.iCustomerID = Ten.DCLink) t2 ON t2.Account = t1.Account AND t2.DCBalance = t1.DCBalance

Correct Syntax When Limiting Results in Sybase SQL Statement Query

I am trying to put a limit on my Sybase SELECT statement query, but I keep getting syntax errors. I've tried using both limit and SELECT * TOP 10, but neither seems to work. This is my SELECT statement code:
SELECT top 10 *
// column params
FROM claims c
LEFT OUTER JOIN claims_transaction as ct
ON ct.claim_id = c.id
LEFT OUTER JOIN claims_batch_listings cb
ON cb.batch_listing = c.batchl
LEFT OUTER JOIN notes_details d
ON d.id_number = c.notes_detail_id
LEFT OUTER JOIN individual_ins_xref px
ON px.pt_id = c.ind_id
AND px.ins_id = c.ins_id
LEFT OUTER JOIN individuals ind
ON ind.id_number = c.ind_id
LEFT OUTER JOIN sections sec
ON ind.sec_id = sec.id_number
LEFT OUTER JOIN contract_items cont
ON c.contract_id = cont.contract_id
WHERE ( d.date_of_visit >= px.coverage_start AND d.date_of_visit <= px.coverage_end )
AND visit_type <> 'No Visit'
ORDER BY c.datetimecreated;
The * is wrong. Just lose it and you should be OK:
SELECT top 10 -- * removed here
c.claim_problem as problem,
-- etc.