Converting T-SQL Left Join Subqueries to MS-Access - sql-server

I need help in converting this T-SQL query to MS ACCESS. The error that I'm getting is JOIN expression not supported.
Update:
I can't add:
DDA ON TT.[Description] = DDA.AccountTypeDesc AND
H.AccountNumber = DDA.AccountNumber
But
DDA ON TT.[Description] = DDA.AccountTypeDesc
works. Is there a way to add the second condition?
T-SQL Query:
SELECT
*
FROM
(
SELECT
[PesoAmount] = CASE WHEN FE.IsoCode IS NULL THEN
LTRIM(STR(DFCF.CurrencyAmount, 20, 2))
ELSE
LTRIM(STR(DFCF.CurrencyAmount * FE.PhpConversionRate, 20, 2))
END,
DFCF.TransactionNumber,
DFCF.AccountNumber,
DFCF.CountryCd,
DFCF.TransactionTypeCd,
DFCF.Time,
DFCF.Date,
DFCF.TransactionStatusCd,
DFCF.TransactionCurrencyCd,
DFCF.BranchNumber,
DFCF.RemitterExtPartyCd,
DFCF.BeneficiaryExtPartyCd,
DFCF.PostedDate,
DFCF.AssociateNumber,
DFCF.ExecutingPartyNumber,
DFCF.CurrencyAmount,
DFCF.CurrencyAmountInTxnCcy,
DFCF.CurrencyAmountInAccountCcy,
DFCF.SecondaryAccountKey,
DFCF.RelatedInd,
DFCF.ThirdPartyInd,
DFCF.TransactionDescription,
DFCF.SecurityName,
DFCF.DealNumber
FROM
dbo.DesFactCashFlow DFCF (NOLOCK) LEFT JOIN
dbo.ForeignExchange FE (NOLOCK) ON DFCF.TransactionCurrencyCd = FE.IsoCode
)
H LEFT JOIN
dbo.Ctr C (NOLOCK) ON H.PesoAmount = C.PesoAmountFaceValueSumInsured AND
H.AccountNumber = C.AccountNumber AND
H.TransactionTypeCd = C.TransactionType LEFT JOIN
dbo.TransactionType TT (NOLOCK) ON H.TransactionTypeCd = TT.Code LEFT JOIN
(
SELECT
[AccountNumber] = DDA2.AccountNumber,
[AccountTypeDesc] = DDA2.AccountTypeDesc,
[LineOfBusinessName] = MAX(DDA2.LineOfBusinessName),
[AccountCurrencyCode] = MAX(DDA2.AccountCurrencyCode),
[AccountCurrencyName] = MAX(DDA2.AccountCurrencyName),
[AccountRegistrationTypeDesc] = MAX(DDA2.AccountRegistrationTypeDesc),
[AccountRegistrationName] = MAX(DDA2.AccountRegistrationName),
[AccountName] = MAX(DDA2.AccountName),
[AlternateName] = MAX(DDA2.AlternateName),
[AccountOpenDate] = MAX(DDA2.AccountOpenDate),
[AccountCloseDate] = MAX(DDA2.AccountCloseDate),
[AccountStatusDesc] = MAX(DDA2.AccountStatusDesc),
[DormantInd] = MAX(DDA2.DormantInd),
[ProductLineName] = MAX(DDA2.ProductLineName),
[ProductCategoryName] = MAX(DDA2.ProductCategoryName),
[ProductTypeName] = MAX(DDA2.ProductTypeName),
[ProductName] = MAX(DDA2.ProductName),
[ProductNumber] = MAX(DDA2.ProductNumber),
[AccountTaxId] = MAX(DDA2.AccountTaxId),
[AccountTaxIdTypeCode] = MAX(DDA2.AccountTaxIdTypeCode),
[AccountTaxStateCode] = MAX(DDA2.AccountTaxStateCode),
[AccountPrimaryBranchName] = MAX(DDA2.AccountPrimaryBranchName),
[MailingAddress1] = MAX(DDA2.MailingAddress1),
[MailingAddress2] = MAX(DDA2.MailingAddress2),
[MailingCityName] = MAX(DDA2.MailingCityName),
[MailingStateCode] = MAX(DDA2.MailingStateCode),
[MailingStateName] = MAX(DDA2.MailingStateName),
[MailingPostalCode] = MAX(DDA2.MailingPostalCode),
[MailingCountryCode] = MAX(DDA2.MailingCountryCode),
[MailingCountryName] = MAX(DDA2.MailingCountryName),
[CurrencyBasedAccountInd] = MAX(DDA2.CurrencyBasedAccountInd),
[MaturityDate] = MAX(DDA2.MaturityDate),
[OriginalLoanAmount] = MAX(DDA2.OriginalLoanAmount),
[CollateralTypeDesc] = MAX(DDA2.CollateralTypeDesc),
[CollateralTypeCode] = MAX(DDA2.CollateralTypeCode),
[InsuredAmount] = MAX(DDA2.InsuredAmount),
[EmployeeInd] = MAX(DDA2.EmployeeInd)
FROM
dbo.DesDimAccount DDA2 (NOLOCK)
GROUP BY
DDA2.AccountNumber,
DDA2.AccountTypeDesc
)
DDA ON RTRIM(TT.[Description]) = RTRIM(DDA.AccountTypeDesc) AND
H.AccountNumber = DDA.AccountNumber
EDIT: I replaced the query with the AS keyword. I get the same error.
MS Access Query with Error:
SELECT
'H' AS [HeaderRecordIndicator],
'1' AS [SupervisingAgency],
'0' + I.InstitutionCode AS [InstitutionCode],
CONVERT(char(8), H.Date, 112) AS [ReportDate],
'CTR' AS [ReportType],
'21' AS [FormatCode],
'1' AS [SubmissionType]
FROM
(((
SELECT
IIF(ISNULL(FE.IsoCode), FORMAT(DFCF.CurrencyAmount, "##################.00"), FORMAT(DFCF.CurrencyAmount * FE.PhpConversionRate, "##################.00")) AS [PesoAmount],
DFCF.TransactionNumber,
DFCF.AccountNumber,
DFCF.CountryCd,
DFCF.TransactionTypeCd,
DFCF.Time,
DFCF.Date,
DFCF.TransactionStatusCd,
DFCF.TransactionCurrencyCd,
DFCF.BranchNumber,
DFCF.RemitterExtPartyCd,
DFCF.BeneficiaryExtPartyCd,
DFCF.PostedDate,
DFCF.AssociateNumber,
DFCF.ExecutingPartyNumber,
DFCF.CurrencyAmount,
DFCF.CurrencyAmountInTxnCcy,
DFCF.CurrencyAmountInAccountCcy,
DFCF.SecondaryAccountKey,
DFCF.RelatedInd,
DFCF.ThirdPartyInd,
DFCF.TransactionDescription,
DFCF.SecurityName,
DFCF.DealNumber
FROM
DesFactCashFlow DFCF LEFT JOIN
ForeignExchange FE ON DFCF.TransactionCurrencyCd = FE.IsoCode
) AS
H LEFT JOIN
Ctr C ON H.PesoAmount = C.PesoAmountFaceValueSumInsured AND
H.AccountNumber = C.AccountNumber AND
H.TransactionTypeCd = C.TransactionType) LEFT JOIN
TransactionType TT ON H.TransactionTypeCd = TT.Code) LEFT JOIN
(
SELECT
DDA2.AccountNumber AS [AccountNumber],
DDA2.AccountTypeDesc AS [AccountTypeDesc],
MAX(DDA2.LineOfBusinessName) AS [LineOfBusinessName],
MAX(DDA2.AccountCurrencyCode) AS [AccountCurrencyCode],
MAX(DDA2.AccountCurrencyName) AS [AccountCurrencyName],
MAX(DDA2.AccountRegistrationTypeDesc) AS [AccountRegistrationTypeDesc],
MAX(DDA2.AccountRegistrationName) AS [AccountRegistrationName],
MAX(DDA2.AccountName) AS [AccountName],
MAX(DDA2.AlternateName) AS [AlternateName],
MAX(DDA2.AccountOpenDate) AS [AccountOpenDate],
MAX(DDA2.AccountCloseDate) AS [AccountCloseDate],
MAX(DDA2.AccountStatusDesc) AS [AccountStatusDesc],
MAX(DDA2.DormantInd) AS [DormantInd],
MAX(DDA2.ProductLineName) AS [ProductLineName],
MAX(DDA2.ProductCategoryName) AS [ProductCategoryName],
MAX(DDA2.ProductTypeName) AS [ProductTypeName],
MAX(DDA2.ProductName) AS [ProductName],
MAX(DDA2.ProductNumber) AS [ProductNumber],
MAX(DDA2.AccountTaxId) AS [AccountTaxId],
MAX(DDA2.AccountTaxIdTypeCode) AS [AccountTaxIdTypeCode],
MAX(DDA2.AccountTaxStateCode) AS [AccountTaxStateCode],
MAX(DDA2.AccountPrimaryBranchName) AS [AccountPrimaryBranchName],
MAX(DDA2.MailingAddress1) AS [MailingAddress1],
MAX(DDA2.MailingAddress2) AS [MailingAddress2],
MAX(DDA2.MailingCityName) AS [MailingCityName],
MAX(DDA2.MailingStateCode) AS [MailingStateCode],
MAX(DDA2.MailingStateName) AS [MailingStateName],
MAX(DDA2.MailingPostalCode) AS [MailingPostalCode],
MAX(DDA2.MailingCountryCode) AS [MailingCountryCode],
MAX(DDA2.MailingCountryName) AS [MailingCountryName],
MAX(DDA2.CurrencyBasedAccountInd) AS [CurrencyBasedAccountInd],
MAX(DDA2.MaturityDate) AS [MaturityDate],
MAX(DDA2.OriginalLoanAmount) AS [OriginalLoanAmount],
MAX(DDA2.CollateralTypeDesc) AS [CollateralTypeDesc],
MAX(DDA2.CollateralTypeCode) AS [CollateralTypeCode],
MAX(DDA2.InsuredAmount) AS [InsuredAmount],
MAX(DDA2.EmployeeInd) AS [EmployeeInd]
FROM
DesDimAccount DDA2
GROUP BY
DDA2.AccountNumber,
DDA2.AccountTypeDesc
) AS
DDA ON RTRIM(TT.[Description]) = RTRIM(DDA.AccountTypeDesc) AND
H.AccountNumber = DDA.AccountNumber
Here is the simplified query with the same error:
SELECT
*
FROM
(((
SELECT
IIF(ISNULL(FE.IsoCode), FORMAT(DFCF.CurrencyAmount, "##################.00"), FORMAT(DFCF.CurrencyAmount * FE.PhpConversionRate, "##################.00")) AS [PesoAmount],
DFCF.TransactionNumber,
DFCF.TransactionCurrencyCd,
FROM
DesFactCashFlow DFCF LEFT JOIN
ForeignExchange FE ON DFCF.TransactionCurrencyCd = FE.IsoCode
) AS
H LEFT JOIN
Ctr C ON H.PesoAmount = C.PesoAmountFaceValueSumInsured AND
H.AccountNumber = C.AccountNumber AND
H.TransactionTypeCd = C.TransactionType) LEFT JOIN
TransactionType TT ON H.TransactionTypeCd = TT.Code) LEFT JOIN
(
SELECT
DDA2.AccountNumber AS [AccountNumber],
DDA2.AccountTypeDesc AS [AccountTypeDesc],
MAX(DDA2.LineOfBusinessName) AS [LineOfBusinessName],
FROM
DesDimAccount DDA2
GROUP BY
DDA2.AccountNumber,
DDA2.AccountTypeDesc
) AS
DDA ON RTRIM(TT.[Description]) = RTRIM(DDA.AccountTypeDesc) AND
H.AccountNumber = DDA.AccountNumber

Give up trying to convert the SQL text from your T-SQL query to Access SQL. Create a new Access query from scratch and use the T-SQL query only as a road map. Add your data sources and set up the joins. The query designer will guarantee you create the joins in the manner which keeps the db engine happy: addition and positioning of parentheses it requires for queries with more than one join; the rules which apply for LEFT JOINs; and so forth. Just let the designer handle those details for you.
The designer will choke in Design View due to the functions in this part of your last join:
RTRIM(TT.[Description]) = RTRIM(DDA.AccountTypeDesc)
So leave out the RTRIM() functions while you're setting up the joins in Design View. Don't worry that the query doesn't return the correct results. After you get joins which satisfy the db engine, switch to SQL View and add the RTRIM() functions back in.
After you get the joins set up correctly, then add in your field expressions to the SELECT list.
Also you may find it easier to manage your complex query by breaking out the subqueries as separate saved queries --- then reference those queries by name in the master query just as you would table sources.

The problem is with the penultimate line:
DDA ON RTRIM(TT.[Description]) = RTRIM(DDA.AccountTypeDesc) AND
The Design View of the Access query designer can't work with functions in the ON part of the clause. You must remove the RTRIM.

Access is parenthesis happy. Wrap each join expression in parentheses, the ON clauses themselves, and each pair of tables.
You can't use CONVERT, NOLOCK, or CASE.

Which version of MSAccess you are using in your system? I just tried in 2007 version and RTRIM is working.

Related

SQL - How to include NULL values when using MAX() function?

I am trying to create a report where it only shows the newest CoverageGroup, including null values.
Sample - Current VS Want
Here is the current code (without MAX() function):
SELECT
p.AcctNumber,
c.sDate,
ISNULL(cv.Coveragegroup,0) AS [CoverageGroup],
wd.Code,
ISNULL(CO2.lname,'Patient') AS [PrimIns],
p.DefaultCoverageGroup,
ISNULL(cv.LevelOfCoverage,0) AS [LevelOfCoverage]
FROM
Patient p
FULL OUTER JOIN
Charge c ON c.PatientID = p.IDPatient
FULL OUTER JOIN
Coverage cv ON cv.PatientiD = p.IDPatient
FULL OUTER JOIN
WorkDescriptor wd ON wd.IDWorkdescriptor = c.WorkDescriptorID
FULL OUTER JOIN
InsCompany ic on ic.IDInsCompany = cv.InsCompanyID
FULL OUTER JOIN
Contact co2 on co2.IDContact = ic.ContactID
WHERE
p.AcctNumber IN (256500, 256569)
AND (cv.Coveragegroup = p.DefaultCoverageGroup OR p.DefaultCoverageGroup = 0)
AND (cv.LevelOfCoverage = 1 OR cv.LevelOfCoverage IS NULL)
ORDER BY
p.AcctNumber, c.sDate
I've tried different variations of MAX(COALESCE... and MAX(CASE WHEN... but they didn't work or they would not show accounts with a null CoverageGroup.
Any idea how I could do this? My expertise in SQL is beginner.
Thank you!
It is maybe because of this:
AND (cv.Coveragegroup = p.DefaultCoverageGroup OR p.DefaultCoverageGroup = 0)
Here you actually specify that it is not allowed to be NULL.
You can maybe avoid it by changing it to something like this:
AND (cv.Coveragegroup = p.DefaultCoverageGroup OR p.DefaultCoverageGroup = 0 OR cv.Coveragegroup IS NULL)

SQL Query for list within select where field = value and otherfield = othervalue

I need to fudge an existing SQL Server procedure rather quickly. It's a bit of a hack job but needs must.
I need for the following to return a list of voucher codes and invoice numbers rather than just one row of data where the comment is (in the WHERE clause):
SELECT TOP 10
IH.INH_Voucher AS [ID], IH.COY_ID AS COY_ID,
IH.INH_DateSupInv AS ORD_UpdatedOn,
V.VES_ID, V.VES_IMOnumber, IH.INH_Order,
IH.INH_ID AS ORD_ID, IH.INH_INDID
FROM
InvoiceHDR IH (NOLOCK)
INNER JOIN
VESSACCOMP VA ON IH.COY_ID = VA.COY_ID
INNER JOIN
Vessel V ON VA.VES_ID = V.VES_ID
WHERE
v.VSS_ID IN ('01') AND
(IH.INH_Status >= 20 AND IH.INH_Status <= 40) AND
--IH.INH_Voucher = '170CH' AND IH.INH_SupInv = '1532' NEED LIST
IH.INH_INDID IS NOT NULL
So I would need
Voucher = '1700CH' AND SupInv = '1235' AND
Voucher = '180CH' AND SupInv = '1111' AND
And so on for many matching VoucherCodes and InvoiceCodes.
I hope this is clear?
Thanks.
You can apply the following WHERE clause to your query:::
WHERE
v.VSS_ID IN ('01') AND
(IH.INH_Status BETWEEN 20 AND 40) AND
((IH.INH_Voucher = '170CH' AND IH.INH_SupInv = '1532')
OR (IH.INH_Voucher = '180CH' AND IH.INH_SupInv = '1111'))
AND IH.INH_INDID IS NOT NULL

SQL Query Help - searching on multiple 'pairs' or data

I'm struggling to work out how to do a SQL query on a database that I have.
I have a view (which can be changed) which shows the relationships between the tables.
This creates a view as follows:
What I need to be able to do is search on one or more 'Attribute Pairs'
for example
I want to search for records with:
(
(AttributeName='FileExtension' AND AttributeValue='.pdf')
AND (AttributeName='AccountNumber' AND AttributeValue='ABB001'
)
As you can tell, this is not working as AttributeName cant be two things at once. I have this working with an OR filter, but I want it to find records that have all attribute pairs
SELECT
dbo.SiconDMSDocument.SiconDMSDocumentID,
dbo.SiconDMSAttribute.SiconDMSAttributeID,
dbo.SiconDMSAttribute.AttributeFriendlyName,
dbo.SiconDMSAttribute.AttributeName,
dbo.SiconDMSDocumentAttribute.AttributeValue,
dbo.SiconDMSAttribute.DataType,
dbo.SiconDMSDocumentType.SiconDMSDocumentTypeID,
dbo.SiconDMSDocumentType.DocumentTypeName,
dbo.SiconDMSDocumentType.DocumentTypeFriendlyName,
dbo.SiconDMSModule.SiconDMSModuleID,
dbo.SiconDMSModule.ModuleName,
dbo.SiconDMSModule.ModuleFriendlyName,
dbo.SiconDMSDocument.SiconDMSDocumentTypeModuleID
FROM dbo.SiconDMSDocument
INNER JOIN dbo.SiconDMSDocumentAttribute ON dbo.SiconDMSDocument.SiconDMSDocumentID = dbo.SiconDMSDocumentAttribute.SiconDMSDocumentID
INNER JOIN dbo.SiconDMSAttribute ON dbo.SiconDMSDocumentAttribute.SiconDMSAttributeID = dbo.SiconDMSAttribute.SiconDMSAttributeID
AND
(
(dbo.SiconDMSAttribute.AttributeName = 'Reference' AND dbo.SiconDMSDocumentAttribute.AttributeValue='12345')
OR (dbo.SiconDMSAttribute.AttributeName = 'AccountNumber' AND dbo.SiconDMSDocumentAttribute.AttributeValue='ABB001')
)
INNER JOIN dbo.SiconDMSDocumentTypeModule ON dbo.SiconDMSDocument.SiconDMSDocumentTypeModuleID = dbo.SiconDMSDocumentTypeModule.SiconDMSDocumentTypeModuleID
INNER JOIN dbo.SiconDMSDocumentType ON dbo.SiconDMSDocumentTypeModule.SiconDMSDocumentTypeID = dbo.SiconDMSDocumentType.SiconDMSDocumentTypeID
INNER JOIN dbo.SiconDMSModule ON dbo.SiconDMSDocumentTypeModule.SiconDMSModuleID = dbo.SiconDMSModule.SiconDMSModuleID
WHERE
(dbo.SiconDMSDocument.Deleted = 0)
AND (dbo.SiconDMSDocumentAttribute.Deleted = 0)
AND (dbo.SiconDMSAttribute.Deleted = 0)
AND (dbo.SiconDMSDocumentType.Deleted = 0)
AND (dbo.SiconDMSDocumentTypeModule.Deleted = 0)
AND (dbo.SiconDMSModule.Deleted = 0)
Are there any SQL functions that will allow me to do something like this?
I'm not sure what your complicated query has to do with the question of searching for attribute pairs.
Assuming you want the document ids that have both attributes:
select SiconDMSDocumentID
from yourview y
where (AttributeName = 'FileExtension' AND AttributeValue = '.pdf') or
(AttributeName = 'AccountNumber' AND AttributeValue = 'ABB001'
group by SiconDMSDocumentID
having count(*) = 2;
Or, if the attributes could have multiple values:
having count(distinct AttributeName) = 2

To add a condition dynamically in PowerBuilder

I'm new to Power Builder code. I need to add a condition to Join dynamically. Any help is appreciated. Thanks a lot
String szdSQL, psql, sznewsql
szdSQL = "Select A, B, C, D
FROM sy_staging
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id
LEFT OUTER JOIN gl_M
ON sy_staging.id= gl_M.id AND sy_staging.version = gl_M.version
WHERE sy_staging.year = :lyear AND
sy_staging.location = :llocation "
psql = "Upper(fd_M.code3) = 'SMM' "
In my new query I want to add the condition present in this string variable (psql) in the join as below
sznewsql = " "Select A, B, C, D
FROM sy_staging
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id AND Upper(fd_M.code3) = 'SMM'
LEFT OUTER JOIN gl_M
ON sy_staging.id= gl_M.id AND sy_staging.version = gl_M.version
WHERE sy_staging.year = :lyear AND
sy_staging.location = :llocation "
Hmmm... That's an interesting case - adding a parameter to the ON clause, not the WHERE clause.
I'd use a datawindow, for sure (because I always do), but I'm not sure you can do that in graphic mode. You might have to convert to syntax, and then just add the new parameter into the ON clause with the ":" syntax.
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id AND Upper(fd_M.code3) = :newStringParm
LEFT OUTER JOIN gl_M
...
and then your PowerScript would be
dw_1.retrieve( lYear, lLocation, psql )
-Paul Horan-
If you're only going to have those two different SQLs, you could just create two separate datawindows and then dynamically swap out the one used in the datawindow control.

Translating a QueryExpression into SQL: what's a Natural join?

I am trying to translate a QueryExpression that is in some existing code into a T-SQL select statement.
I've run across the following statement and I'm having trouble understanding what they mean by a Natural Join:
linkEntity1.JoinOperator = JoinOperator.Natural;
Would this be equivalent to an Inner Join in T-SQL? Googling has not been much help.
Here's the rest of the QueryExpression Code:
QueryExpression query = new QueryExpression();
query.EntityName = "showinfo";
ColumnSet columns = new ColumnSet();
columns.Attributes = new String[] { "company" };
query.ColumnSet = columns;
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "company";
condition1.Operator = ConditionOperator.NotNull;
query.Criteria.Conditions = new ConditionExpression[] { condition1 };
LinkEntity linkEntity1 = new LinkEntity();
linkEntity1.JoinOperator = JoinOperator.Natural;
linkEntity1.LinkFromEntityName = "show";
linkEntity1.LinkFromAttributeName = "showid";
linkEntity1.LinkToEntityName = "showintegration";
linkEntity1.LinkToAttributeName = "showcode";
linkEntity1.LinkCriteria = new FilterExpression();
linkEntity1.LinkCriteria.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "showend";
condition2.Operator = ConditionOperator.Null;
linkEntity1.LinkCriteria.Conditions = new ConditionExpression[] { condition2 };
query.LinkEntities = new LinkEntity[] { linkEntity1 };
There is no equivalent in SQL Server of a natural join where table intersect is based on column names by the RDBMS.
I'm glad of that because it is at best ambiguous and at worst dangerous. JOINs should be explicit. Examples why:
having a InsertedBy column in both tables (quite common): should we have to prefix with the table name to remove ambiguity?
future DDL that add columns that change JOIN semantics
See
Natural join in SQL Server
SQL Server - lack of NATURAL JOIN / x JOIN y USING(field)
Edit:
It looks like natural join means "don't repeat the column in the output" (like USING in MySQL would do) according to the JoinOperator Enumeration.
If I understand this (debatable!) it's misleading. Especially when I read the "LeftOuter" narrative..
A natural join compares all columns in the two tables that have the same column names. It's equivalent to an inner join with the matching columns explicitly listed.
Yes - the natural join is inner join - so you can write:
select * from tab1, tab2 where tab1.col1 = tab2.col1
as
select * from tab1 inner join tab2 on tab1.col1 = tab2.col1

Resources