Difference in query joins - tsql

I have a query which is dynamically generated.
SELECT '' + CAST(GalleryGallery_tGallery._Name AS VARCHAR(4000)) + '' AS NewName
FROM Photographers_tGalleries
LEFT OUTER JOIN Gallery_tGallery AS GalleryGallery_tGallery
ON BaseContent_tGalleries.[Gallery] = GalleryGallery_tGallery._Guid
LEFT OUTER JOIN BaseContent_tGalleries
ON Photographers_tGalleries._Guid =
BaseContent_tGalleries._Guid_Structure_Content
The joins appear correct to me. However, the query errors with The multi-part identifier "BaseContent_tGalleries.Gallery" could not be bound.
The following query does work. While the joins are matching the correct fields, they are in a different order. I am wondering why this one works and the other does not. We would like to fix the top one but since it is dynamic, I am looking for the least amount of change.
SELECT '' + CAST(GalleryGallery_tGallery._Name AS VARCHAR(4000)) + '' AS NewName
FROM Gallery_tGallery AS GalleryGallery_tGallery
LEFT OUTER JOIN BaseContent_tGalleries
ON GalleryGallery_tGallery._Guid = BaseContent_tGalleries.Gallery
LEFT OUTER JOIN Photographers_tGalleries
ON BaseContent_tGalleries._Guid_Structure_Content =
Photographers_tGalleries._Guid

Your join ordering for the first query is wrong. You need to reference BaseContent_tGalleries before Gallery_tGallery.
SELECT '' + CAST(g._Name AS VARCHAR(4000)) + '' AS NewName
FROM Photographers_tGalleries AS g
LEFT OUTER JOIN BaseContent_tGalleries AS b
ON g._Guid = b._Guid_Structure_Content
LEFT OUTER JOIN Gallery_tGallery AS gg
ON b.[Gallery] = gg._Guid;
Who named your tables and aliases by the way? GalleryGallery_tGallery, really? I've converted to shorter aliases to compensate for whoever really likes typing. A LOT.

The first query doesn't work since you're trying to use the table BaseContent_tGalleries in an ON statement, but it has not been joined yet. In other words, you're using a table as a join condition, but the table itself hasn't been joined yet.

Related

Postgresql :joining on fields using CASE expression

I am trying to join two tables on two fields with a below condition
If condition 1 is satisfied then join ON a.field_1 = b.field_1
If condition 2 is satisfied then join ON a.field_2 = b.field_2
In order to do so, I am writing the below query
SELECT
a.field_1,a.field_2,
b.field_1,b.field_2 FROM table a
INNER JOIN table b
CASE WHEN COALESCE(TRIM(a.field_1),'') = '' THEN a.field_1 = b.field_1
ELSE a.field_2 = b.field_2 END
I am not sure whether this would run.
From the manual:
T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression
A JOIN accepts an arbitrary "boolean expression", which may reference columns from both joined relations. While the trivial form is t1.col = t2.col, the boolean expression is not limited to it and so comparing two sets of columns based on some other column is totally fine.
Please note your syntax error #sticky bit pointed out.

SQL Server: How to customize one column in Order By clause out of many other columns in order by

I have store procedure which return data fine and it was developed by some one else who now not in touch.
Output now looks like
Here i am attaching a part of the query which return data.
SET #sql = '
Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,
Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator
From
(
---- Broker Detail
Select AA.Section,AA.LineItem,Csm.DisplayInCSM ,AA.BrokerCode Broker,AA.BrokerName,'''' BM_Element,'''' BM_Code,AA.Ord,AA.[Revise Date],AA.LineItemId,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+#PeriodCols+','+#PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From tblCSM_ModelDetails Csm LEFT OUTER JOIN (
Select b.*,L.ID LineItemId
From #TmpAll_Broker_LI b
INNER JOIN TblLineItemTemplate L ON TickerID='''+#TickerID+''' AND b.LineItem= L.LineItem
) AA ON Csm.LineItemId=AA.LineItemId
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),#CSM_Id))+' AND Csm.BMID=0 AND Type !=''SHEET''
UNION
----- Consensus
Select Section, b.LineItem,DisplayInCSM, '''' Broker,'''' BrokerName,'''' BM_Element,'''' BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+#PeriodCols+','+#PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpZacksCons b
INNER JOIN TblLineItemTemplate L ON TickerID='''+#TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),#CSM_Id))+' AND Csm.BMID=0
---- Blue Metrics
UNION
Select Section, b.LineItem,DisplayInCSM,'''' Broker,'''' BrokerName,BM_Element,Code BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+#PeriodCols+','+#PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpBM b
INNER JOIN TblLineItemTemplate L ON TickerID='''+#TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.BMID=b.code AND Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),#CSM_Id))+'
AND Ord IS NOT NULL
) XX
Left Outer Join tblLiConfig ZZ
On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+#Ticker+'''
Order by ID,Ord,BM_Code,LineItem,BrokerName'
Now broker Name is not coming as alphabetical order and it is the issue.
see this line at the bottom Order by ID,Ord,BM_Code,LineItem,BrokerName
When i try to change this order by like Order by ID,Ord,BM_Code,LineItem,BrokerName IN (SELECT BrokerName FROM #Brokers ORDER BY BrokerName ASC)' then getting error like clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
in my order by there are many columns and data is getting order by that way but i need to show broker name in alphabetical order but i am not being able. so please some one guide me how can i customize this sql.
Here i have not attached my full store procedure code because it is very large. looking for suggestion & help. Thanks
Short version
The ORDER BY is doing what is expected - ordering first by ID, then Ord, then BM_Code, then LineItem, then BrokerName.
Within ID 76187, the next field to order by is Ord - which it sorts from 30911, to 31097.
If it previously ordered by BrokerName, it was only by chance - or that Ord was ordered the same way as BrokerName.
My initial suggestion is to re-order your sort e.g., ORDER BY ID, BM_Code, LineItem, BrokerName, Ord
Longer explanation of issue
In SQL, underlying data is treated as a set and ordering doesn't matter.
For example, if you have a variable #x and you were testing IF #x IN (1,2,3,4,5) will produce the same result as IF #x in (5,4,3,2,1).
In your example, you're putting an ORDER BY into the sub-query you're checking with the IN e.g., ORDER BY ... BrokerName IN (SELECT BrokerName FROM #Brokers ORDER BY BrokerName ASC). The order of that sub-query isn't allowed, and wouldn't do anything anyway.
The only sort that matters (other than for a few things like TOP) is the final sort - when displaying the data.
That being said, even if you removed the ORDER BY in the sub-query, it wouldn't help you with your issue
The SQL is not likely to work anyway - ORDER BY needs a value - you may have needed to make it CASE WHEN BrokerName IN (...) THEN 0 ELSE 1 END
Which also won't help, as the issue is that Ord is sorted before BrokerName anyway.
UPDATE following comment
Fundamentally, the statement that provides the actual report is
SET #sql = '
Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,
Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator
From (<a whole lot of calculations/cpode>) XX
Left Outer Join tblLiConfig ZZ
On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+#Ticker+'''
Order by ID,Ord,BM_Code,LineItem,BrokerName'
The last line on there provides the ordering of the data coming from this procedure.
To get a different order, you need to change the order of the fields shown - moving BrokerName more towards the start of the list, and Ord towards the end.
e.g.,
SET #sql = '
Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,
Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator
From (<a whole lot of calculations/cpode>) XX
Left Outer Join tblLiConfig ZZ
On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+#Ticker+'''
Order by ID,BrokerName,BM_Code,LineItem,Ord'
The above probably sorts by BrokerName too early - but it's up to you to determine what you need.

SQL case when in join

I have a query with 2 tables that I want to join, but do to a software bug I can't always join them the same way. The TICKC table is supposed to have a foreignkey populated which would allow a join to the LABLOG table, however it's not always populated, and when it isn't populated I need to join it a different way. So I want to know how to write the join so that it joins on the foreign key if it's present, and if it isn't present then it should join on a different condition. This backup condition always exists, but the primary doesn't always exist.
LEFT OUTER JOIN TICKC
ON tickc.DELFLAG=0 and TICKC.LABLOGNO = LABLOG.CPK_LABLOG *This is the ideal join, but if TICKC.LABLOGNO is blank then it should join like this instead:*
tickc.NEXTCODE = LABLOG.SCRIPTEXT AND CONVERT(VARCHAR(10),TICKC.CREATEDON, 20) = CONVERT(VARCHAR(10),LABLOG.CREATEDON, 20)
Any help is appreciated, thank you
You could do something like this:
LEFT OUTER JOIN TICKC
ON (
tickc.DELFLAG = 0
AND TICKC.LABLOGNO = LABLOG.CPK_LABLOG
)
OR (
TICKC.LABLOGNO IS NULL
AND tickc.NEXTCODE = LABLOG.SCRIPTEXT
AND CONVERT(VARCHAR(10),TICKC.CREATEDON, 20) = CONVERT(VARCHAR(10),LABLOG.CREATEDON, 20)
)

T-SQL Getting duplicate rows returned

The following code section is returning multiple columns for a few records.
SELECT a.ClientID,ltrim(rtrim(c.FirstName)) + ' ' +
case when c.MiddleName <> '' then
ltrim(rtrim(c.MiddleName)) + '. '
else ''
end +
ltrim(rtrim(c.LastName)) as ClientName, a.MISCode, b.Address, b.City, dbo.ClientGetEnrolledPrograms(CONVERT(int,a.ClientID)) as Abbreviation
FROM ClientDetail a
JOIN Address b on(a.PersonID = b.PersonID)
JOIN Person c on(a.PersonID = c.PersonID)
LEFT JOIN ProgramEnrollments d on(d.ClientID = a.ClientID and d.Status = 'Enrolled' and d.HistoricalPKID is null)
LEFT JOIN Program e on(d.ProgramID = e.ProgramID and e.HistoricalPKID is null)
WHERE a.MichiganWorksData=1
I've isolated the issue to the ProgramEnrollments table.
This table holds one-to-many relationships where each ClientID can be enrolled in many programs. So for each program a client is enrolled in, there is a record in the table.
The final result set is therefore returning a row for each row in the ProgramEnrollments table based on these joins.
I presume my join is the issue but I don't see the problem.
Thoughts/Suggestions?
Thanks,
Chuck
The JOIN is not the issue, it's doing what it's meant to do with a one-to-many relationship
You could use a GROUP BY statement on your query, or alternatively use a sub-select to return DISTINCT values from the ProgramEnrollments/Program tables.
You don't seem to be using data from the ProgramEnrollments or Program tables so are they needed in the query (I presume they are, just thought I'd ask the question).
You don't actually appear to be using any columns in ProgramEnrollments or Program, so try removing those 2 JOINs.

Joining several tables: table specified more than once error

I am attempting to call data after joining all of my tables in a postgreSQL query.
I am getting the following error:
Error in postgresqlExecStatement(conn, statement, ...) :
RS-DBI driver: (could not Retrieve the result : ERROR: table name "place" specified more than once
)
Failed to execute SQL chunk
After referring to similar posts and online resources, I have attempted setting aliases (which only create new errors about not referring to the other tables in the FROM clause), reordering the table names (the cleanest, reordered chunk is posted below), and experimenting with UPDATE/FROM/JOIN as an alternative to SELECT/FROM/JOIN. However, I think I ultimately need to be using the SELECT clause.
SELECT *
FROM place
INNER JOIN place ON place.key = form.key
INNER JOIN form ON form.id = items.formid
INNER JOIN items ON items.recid = rec.id
INNER JOIN rec ON rec.id = sub.recid
INNER JOIN sub ON sub.id = type.subid
INNER JOIN type ON type.name = det.typeid;
You have "place" in your query twice, which is allowed but you would have to alias the second use of the table "place". Also you reference something called "det", but it's not a table or alias anywhere in your query. If you want only one place that's fine, just remove the INNER JOIN place and move your place.key = form.key to the form join or to a where clause.
If you want to place tables in their because you are trying to join the table to itself the alias the second one, but you will want to make sure that you then have a clause to join those two tables on (could be part of an on or a where)
The issue ended up being the order of table names. The code below joined everything just fine:
SELECT *
FROM place
INNER JOIN form ON place.key = form.key
INNER JOIN items ON form.id = items.formid
INNER JOIN rec ON items.recid = rec.id
INNER JOIN sub ON rec.id = sub.recid
INNER JOIN type ON sub.id = type.subid
INNER JOIN det ON type.name = det.typeid;