Query Join? Include all records from table
Question posted by: JC2710
(Member)
on
May 30th, 2008 12:06 PM
HI
I have 2 tables ProductType and Sales.
I am trying write a query which gives me a summary of Product Types and Sales for each Product.
Product.....................Sales
A..............................100
B...............................50
C...............................250
D................................0
E................................20
However when I run my query I get
Product.....................Sales
A..............................100
B...............................50
C...............................250
E................................20
Product D is missing because it has no Sales. However I still want it included in results of Query. I have tried left and right joins but they still wont return all the products in the products table?
Can anyone help?
Thanks
Would you like to answer this question?
Sign up for a free account, or Login (if you're already a member).
|
|
May 30th, 2008 12:34 PM
# 2
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by JC2710
HI
I have 2 tables ProductType and Sales.
I am trying write a query which gives me a summary of Product Types and Sales for each Product.
Product.....................Sales
A..............................100
B...............................50
C...............................250
D................................0
E................................20
However when I run my query I get
Product.....................Sales
A..............................100
B...............................50
C...............................250
E................................20
Product D is missing because it has no Sales. However I still want it included in results of Query. I have tried left and right joins but they still wont return all the products in the products table?
Can anyone help?
Thanks
|
You could use a LEFT JOIN (or RIGHT JOIN)
SELECT Product.Name, Sales.Total
FROM Product
LEFT JOIN Sales
ON Product.Product_ID=Sales.Product_ID
check the following :
W3school SQL LEFT JOIN
|
|
May 30th, 2008 12:56 PM
# 3
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by pod
You could use a LEFT JOIN (or RIGHT JOIN)
SELECT Product.Name, Sales.Total
FROM Product
LEFT JOIN Sales
ON Product.Product_ID=Sales.Product_ID
check the following :
W3school SQL LEFT JOIN
|
I am but it doesnt work. Maybe because I have a WHERE stmt included in the Query?
|
|
June 2nd, 2008 05:48 PM
# 4
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by JC2710
I am but it doesnt work. Maybe because I have a WHERE stmt included in the Query?
|
it's possible. See if you can make it work first without the WHERE statement first.
|
|
June 2nd, 2008 07:59 PM
# 5
|
Re: Query Join? Include all records from table
Hi. To add to Pod's reply, if you remove the where clause and the query does return a value for the missing grouping then the reason you don't see the group when the WHERE clause is present is because your WHERE clause does not work with Null values for the compared fields.
To explain, if there are no rows to return for a particular grouping in an outer-joined query any calculated field on the 'other side' of the outer join for that grouping will be returned as a null. If your WHERE clause was, say, WHERE SALES > 0 this will exclude rows where SALES is null, because nulls are not compatible with any other type of value.
In handling nulls you either have to test for them explicitly, or convert them to typed values which the comparison can handle correctly.
It would be easier to guide you if you posted the SQL of your query, including the WHERE clause, for us to check.
-Stewart
|
|
June 3rd, 2008 03:20 PM
# 6
|
Re: Query Join? Include all records from table
Thanks for your help guys!
My query works without the WHERE
Code: ( text )
SELECT tblProductType.ProductType, Sum(tblEstimates.Price) AS SumOfPrice FROM tblProductType LEFT JOIN tblEstimates ON tblProductType.ID = tblEstimates.ProductTypeID GROUP BY tblProductType.ProductType;
But doesnt include all ProductTypes with WHERE....the WHERE stmt has 2 dates.
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, Count(tblProductType.ID) AS [Count of Estimates] FROM tblProductType LEFT JOIN tblEstimates ON tblProductType.ID = tblEstimates.ProductTypeID WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType;
So is there any way of using a left join with a WHERE??
|
|
June 3rd, 2008 03:54 PM
# 7
|
Re: Query Join? Include all records from table
Hi. The WHERE clause just needs a minor alteration to include any rows where a field from the estimate table is null (which indicates that there were no estimates for that particular product over the chosen period). The OR'd IS NULL added to your WHERE clause below should do this:
Code: ( text )
WHERE (((tblEstimates.Deleted)=0) AND ( (tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) OR (tblEstimates.DateReceived IS Null) GROUP BY tblProductType.ID, tblProductType.ProductType;
-Stewart
|
|
June 3rd, 2008 04:15 PM
# 8
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by Stewart Ross Inverness
Hi. The WHERE clause just needs a minor alteration to include any rows where a field from the estimate table is null (which indicates that there were no estimates for that particular product over the chosen period). The OR'd IS NULL added to your WHERE clause below should do this:
Code: ( text )
WHERE (((tblEstimates.Deleted)=0) AND ( (tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) OR (tblEstimates.DateReceived IS Null) GROUP BY tblProductType.ID, tblProductType.ProductType;
-Stewart
|
Thanks for all your help guys! Works great!
|
|
June 6th, 2008 12:57 PM
# 9
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by JC2710
Thanks for all your help guys! Works great!
|
HELP!!!!
I cant get this to work!!!
Adding WHERE tblEstimates.DateReceived Is Null works on the query I stated above but I have an almost identical query and it doesnt work!!
Code: ( text )
SELECT tblStatus.ID, tblStatus.Status, Count(tblEstimates.ID) AS [Count of Estimates] FROM tblStatus LEFT JOIN tblEstimates ON tblStatus.ID = tblEstimates.StatusID WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmStatus_Summary_Report]![txtDateFrom] And [Forms]![frmStatus_Summary_Report]![txtDateTo])) GROUP BY tblStatus.ID, tblStatus.Status;
Then I add OR tblEstimates.DateReceived IS NULL
And the left join still wont work!!!
So frustrating!! Any ideas?
|
|
June 6th, 2008 01:25 PM
# 10
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by Stewart Ross Inverness
Hi. The WHERE clause just needs a minor alteration to include any rows where a field from the estimate table is null (which indicates that there were no estimates for that particular product over the chosen period). The OR'd IS NULL added to your WHERE clause below should do this:
Code: ( text )
WHERE (((tblEstimates.Deleted)=0) AND ( (tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) OR (tblEstimates.DateReceived IS Null) GROUP BY tblProductType.ID, tblProductType.ProductType;
-Stewart
|
Sorry Stewart
Looks like your previous suggestion doesnt work!!
If I add the OR (tblEstimates.DateReceived IS Null) it only brings back ProductTypes that have no estimates related to them at all, not no estimates related to them between the two dates!!
All i want is a simple LEFT JOIN that works!!
Has anyone ever made anything in SQL work apart from SELECT Field FROM table!!
Im starting to wonder!!
Ho hum another cpl of days wasted!!
If you can help Stewart I would be grateful!!
Thanks
|
|
June 9th, 2008 08:54 AM
# 11
|
Re: Query Join? Include all records from table
Hi. SQL is a very powerful query language - but to use it to good effect we need to be very clear about what we are trying to achieve. I think there has been a lack of clarity, reflected in experiments with SQL which do not achieve what you want. These are not a waste, as you will always learn more when you try to resolve problems for yourself this way.
What you want to achieve:
1. You want to total sales activity for your products between two dates.
2. You want to show all products which DO NOT have any sales totals between two dates.
I did not take into account the dates for (2) when going over the left-join requirements with you, and should have recognised that to satisfy requirements 1 and 2 we need two queries, which can be combined in one SQL statement if necessary, but it is still two queries. The first to calculate the totals, and the second to left-join these back to the products table. Showing these as separate (cascaded) queries based on your earlier posts:
Code: ( text )
SELECT tblProductType.ID AS ProductID, Count(tblProductType.ID) AS [Count of Estimates] FROM tblProductType WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType;
I have named this one qryEstimatesCount, so it can be used in
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, [Count of Estimates] FROM tblProductType LEFT JOIN qryEstimatesCount ON tblProductType.ID = ProductID GROUP BY tblProductType.ID, tblProductType.ProductType;
but it ought to be possible to include these in one SQL query as follows
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, [Count of Estimates] FROM tblProductType LEFT JOIN (SELECT tblProductType.ID AS ProductID, Count(tblProductType.ID) AS [Count of Estimates] FROM tblProductType WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType) ON tblProductType.ID = ProductID GROUP BY tblProductType.ID, tblProductType.ProductType;
but I haven't tried this out to check. The two-query cascade approach will certainly do the SELECT the totals you want, then LEFT JOIN this back to the products table as necessary.
-Stewart
|
|
June 9th, 2008 02:19 PM
# 12
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by Stewart Ross Inverness
Hi. SQL is a very powerful query language - but to use it to good effect we need to be very clear about what we are trying to achieve. I think there has been a lack of clarity, reflected in experiments with SQL which do not achieve what you want. These are not a waste, as you will always learn more when you try to resolve problems for yourself this way.
What you want to achieve:
1. You want to total sales activity for your products between two dates.
2. You want to show all products which DO NOT have any sales totals between two dates.
I did not take into account the dates for (2) when going over the left-join requirements with you, and should have recognised that to satisfy requirements 1 and 2 we need two queries, which can be combined in one SQL statement if necessary, but it is still two queries. The first to calculate the totals, and the second to left-join these back to the products table. Showing these as separate (cascaded) queries based on your earlier posts:
Code: ( text )
SELECT tblProductType.ID AS ProductID, Count(tblProductType.ID) AS [Count of Estimates] FROM tblProductType WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType;
I have named this one qryEstimatesCount, so it can be used in
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, [Count of Estimates] FROM tblProductType LEFT JOIN qryEstimatesCount ON tblProductType.ID = ProductID GROUP BY tblProductType.ID, tblProductType.ProductType;
but it ought to be possible to include these in one SQL query as follows
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, [Count of Estimates] FROM tblProductType LEFT JOIN (SELECT tblProductType.ID AS ProductID, Count(tblProductType.ID) AS [Count of Estimates] FROM tblProductType WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType) ON tblProductType.ID = ProductID GROUP BY tblProductType.ID, tblProductType.ProductType;
but I haven't tried this out to check. The two-query cascade approach will certainly do the SELECT the totals you want, then LEFT JOIN this back to the products table as necessary.
-Stewart
|
Thnaks for your help Stewart!
Appreciate it!
Sorry if i sound frustrated!!!
I will tr this out when I get the chance later today!!
Thanks again
|
|
June 9th, 2008 04:23 PM
# 13
|
Re: Query Join? Include all records from table
Hi. I saw that you had posted a response which may have been edited to be just the letters 'dgfgddfgdfgdfgdfgdfgdfgdfgdfgdf' so I deleted it in my Moderator capacity.
I tried out the one-query Left-join approach myself without success this afternoon, so I may be leading you astray thinking that the two could be combined. I will check this out further and let you know.
If the two-query version is working for you then you do indeed have a viable solution. This is the approach I use myself for all such two-stage queries (do some grouping then left-join results). I think it is easier to follow, and allows for re-use of the first stage totalling query to do other jobs if necessary without rewriting.
-Stewart
|
|
June 10th, 2008 01:39 PM
# 14
|
Re: Query Join? Include all records from table
Interesting.
Let me know if this works for you. If not, then your first step is to specify as clearly and logically as you can exactly what you require from the SQL. This will help you as well as anyone trying to assist you. It's almost impossible to work logically without a clear and defined understanding of what's required.
As a last point, please remember to post all your code (including SQL) in the code tags provided. This is a requirement on this site, as not doing so wastes so much time and effort for people trying to assist.
|
|
June 11th, 2008 10:49 AM
# 15
|
Re: Query Join? Include all records from table
Hi Stewart
Thanks again for all your help.
Yes the "dfgfdfgdfdfdfgdfdfg" was me editing my post as I couldnt work out how to delete it! Sorry!
I think Ive solved my problem! Have used your theory, which just needed tweaking slightly.
Anyway this is the final SQL which seems to work! Which combines the 2 queries!
Code: ( text )
SELECT tblProductType.ID, tblProductType.ProductType, T2.[Count of Estimates] FROM tblProductType LEFT JOIN (SELECT tblProductType.ID AS ProductID, Count(tblEstimates.ID) AS [Count of Estimates] FROM tblProductType LEFT JOIN tblEstimates ON tblProductType.ID = tblEstimates.ProductTypeID WHERE (((tblEstimates.Deleted)=0) AND ((tblEstimates.DateReceived) Between [Forms]![frmProductType_Summary_Report]![txtDateFrom] And [Forms]![frmProductType_Summary_Report]![txtDateTo])) GROUP BY tblProductType.ID, tblProductType.ProductType) AS T2 ON tblProductType.ID = T2.ProductID GROUP BY tblProductType.ID, tblProductType.ProductType, T2.[Count of Estimates];
I can now move on to other problems!
Thanks again for all your help. Im sure Ill be needing it again soon!
Thanks
James
|
|
June 11th, 2008 10:57 AM
# 16
|
Re: Query Join? Include all records from table
Well done James, particularly for sorting out the syntax of the single-query version. Excellent!
-Stewart
|
|
June 24th, 2008 10:45 AM
# 17
|
Re: Query Join? Include all records from table
Hi Stewart
Afraid Im stuck again!
I have more or less the same problem as above.
I have tblEstimates holding estimates, linked to tblEstimators. Each Estimate has a status ie Work In Progress, Won , Lost. This is linked to tblStatus. Simple so far. So when I do a query to see the status of Estimates for each estimator. I do a simple GROUP query. However I get the same problem as before where it only includes status's for each estimator that exist.
So if the estimator has Won 3 estimates it shows and if they have Lost 2 it shows. But if they have Won 3 and Lost 0, it only shows them as Won 3, and Lost doesnt appear! However the solution above that we worked out wont work because its broken down by each Estimator and you end up with NULL in estimator field. Dont know if this makes sense.
Have included the query below:
Code: ( text )
SELECT tblEstimates.EstimatorID, tblEstimators.EstimatorName, Sum(tblEstimates.Price) AS SumOfPrice, Sum(tblEstimates.ActualPrice) AS SumOfActualPrice, tblEstimates.StatusID, tblStatus.Status, Count(tblStatus.Status) AS CountOfStatus FROM (tblEstimates LEFT JOIN tblStatus ON tblEstimates.StatusID = tblStatus.ID) RIGHT JOIN tblEstimators ON tblEstimates.EstimatorID = tblEstimators.ID WHERE (((tblEstimates.DateReceived) Between [Forms]![frmEstimator_Summary_Report]![txtDateFrom] And [Forms]![frmEstimator_Summary_Report]![txtDateTo]) AND ((tblEstimates.Deleted)=0)) GROUP BY tblEstimates.EstimatorID, tblEstimators.EstimatorName, tblEstimates.StatusID, tblStatus.Status HAVING (((tblEstimates.EstimatorID)=[Forms]![frmEstimator_Summary_Report]![cboEstimator])) OR ((([tblEstimates]![EstimatorID] Like [Forms]![frmEstimator_Summary_Report]![cboEstimator]) Is Null));
So basically I get:
Estimator Name: Smith
Won: 3
Whereas I want:
Estimator Name: Smith
Won: 3
Lost: 0
Any ideas?
Thanks
|
|
June 24th, 2008 11:27 AM
# 18
|
Re: Query Join? Include all records from table
Solution as before is to separate the two issues - the counting of the number of estimates and the outer-joining of the estimators.
Devise an outer-joined summary query which provides the counts for each estimator by joining the estimates and status tables as in your example SQL, but without including the estimators table in the query. Save this estimate count query. Left-join the count query to the estimators to get your final results, using Nz or similar to convert null values for the counts to zeros.
You will find it much easier to break the problem down into steps which lead on from one to the next than to try to solve this all-in-one, particularly when using outer joins. An advantage is that you can check that the count query is returning correct results before you try outer joining the results back to the estimators.
-Stewart
|
|
June 26th, 2008 12:58 PM
# 19
|
Re: Query Join? Include all records from table
Hi Stewart
Thanks for the advice! Sorry, I was in one of my SQL moods!!!
I think ive solved it! I did 3 querys. The first to Select All Estimators and All Status's, which returned each status with each estimator. Then I did a group by query to get all estimates and then finally a query that joined the two using NZ as before for the NULLS.
Seems to work. And I figured it out before you posted yr advice!! So im obviously learning from yr excellent teaching!! :o)
Thanks again!
Im sure ill be back!!
James
|
|
June 27th, 2008 10:02 AM
# 20
|
Re: Query Join? Include all records from table
Good for you James :)
It's always nice to see members visibly progressing and learning as time goes on.
|
|
July 25th, 2008 01:19 AM
# 21
|
Re: Query Join? Include all records from table
Everyone,
I have found this discussion very helpful in solving essentially the same problem and I wish I had come to this realization a long time ago. I was able to follow the comments left by JC2710 in post 15 of this thread and create a query that gives me the results the way I want them.
However I am running into a problem when I save the query in MS Access. What I input as the SQL code is as follows:
Code: ( text )
SELECT [tblItems].[Team], [tblItems].[Group], [T2].[SumofPicks] FROM tblItems LEFT JOIN (SELECT [tblItems].[Group], Nz(Sum([tblDataHistory].[Picks]),0) AS [SumofPicks] FROM tblItems LEFT JOIN tblDataHistory ON [tblItems].[Item] = [tblDataHistory].[Item] WHERE (((Format([tblDataHistory].[Date],"ww")) Between Format(Date(),"ww")-2 And Format(Date(),"ww")-1)) GROUP BY [tblItems].[Group] ) AS T2 ON [tblItems].[Group] = [T2].[Group] GROUP BY [tblItems].[Team], [tblItems].[Group], [T2].[SumofPicks];
When I reopen the query and view the SQL Code again MS Access has changed it to:
Code: ( text )
SELECT [tblItems].[Team], [tblItems].[Group], [T2].[SumofPicks] FROM tblItems LEFT JOIN [SELECT [tblItems].[Group], Nz(Sum([tblDataHistory].[Picks]),0) AS [SumofPicks] FROM tblItems LEFT JOIN tblDataHistory ON [tblItems].[Item] = [tblDataHistory].[Item] WHERE (((Format([tblDataHistory].[Date],"ww")) Between Format(Date(),"ww")-2 And Format(Date(),"ww")-1)) GROUP BY [tblItems].[Group] ]. AS T2 ON [tblItems].[Group] = [T2].[Group] GROUP BY [tblItems].[Team], [tblItems].[Group], [T2].[SumofPicks];
For some reason Access is changing the parentheses () that open and close the nested query T2 into brackets [] and adding a period at the end.
Anyone have a clue why this might be happening?
Any help here is appreciated!
Last edited by jghouse : July 25th, 2008 at 02:16 AM.
Reason: Found part of the reason for the error
|
|
July 25th, 2008 02:25 AM
# 22
|
Re: Query Join? Include all records from table
I didn't get it in before the edit timer on the last post but the reason this change is a problem is because it will not allow me to come in and edit the SQL and save it again because it has a syntax error in the FROM clause.
|
|
July 25th, 2008 03:38 PM
# 23
|
Re: Query Join? Include all records from table
Hi jghouse. The problem you describe is unfortunately an Access bug. it seems to arise with valid SQL statements which Access is unable to show graphically in design view. I know of no fix for it, I'm sorry to say.
On the occasions I edit such statements I have to change the incorrect rectangular bracketing manually.
-Stewart
|
|
July 25th, 2008 05:34 PM
# 24
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by Stewart Ross Inverness
Hi jghouse. The problem you describe is unfortunately an Access bug. it seems to arise with valid SQL statements which Access is unable to show graphically in design view. I know of no fix for it, I'm sorry to say.
On the occasions I edit such statements I have to change the incorrect rectangular bracketing manually.
-Stewart
|
Stewart,
Thank you for the response. Upon working on this more today I have found that I am able to save it with the rectangular bracketing and period in there now.
The only change I made to get this to work was to remove all other bracketing in the SQL statement. Specifically aroud the portion where I rename the Nz(Sum(...)) As [x] portion. I have removed the brackets around x and now the query will save and can be edited even with the square brackets. I have no clue why this works but it seems to repeat well.
I really wish I could explain how Access reads that SQL with the extra [] and period but it does work, saves, and is editable with no problems.
I have pasted the working code below for reference:
Code: ( text )
SELECT tblItems.Team, tblItems.Group, T2.SumofPicks FROM tblItems LEFT JOIN [SELECT tblItems.Team, tblItems.Group, Nz(Sum(tblDataHistory.Picks),0) AS SumofPicks FROM tblItems INNER JOIN tblDataHistory ON tblItems.Item = tblDataHistory.Item WHERE ((Format(tblDataHistory.Date,"ww")) Between Format(Date(),"ww")-2 And Format(Date(),"ww")-1) GROUP BY tblItems.Team, tblItems.Group ]. AS T2 ON (tblItems.Team = T2.Team) AND (tblItems.Group = T2.Group) GROUP BY tblItems.Team, tblItems.Group, T2.SumofPicks ORDER BY tblItems.Team, tblItems.Group;
|
|
July 28th, 2008 12:58 PM
# 25
|
Re: Query Join? Include all records from table
I use the function below when getting SQL from out of a QueryDef.
It's true, there are times in later versions when the square brackets are accepted, but they are not standard SQL even then.
Code: ( text )
'GetSQL gets the SQL component from a named query OR a SQL string. 'When subqueries are specified in MS Access they are changed internally 'from "FROM (SELECT blah blah blah) AS" to 'either "FROM [SELECT blah blah blah]. AS" 'or "FROM [SELECT blah blah blah] AS" both of which are invalid SQL. 'This code assumes any effected subquery will start with " [SELECT ". 'This reverts SQL to correct format and loses ';' at end if requested. ' 11/11/2004 Updated to detect second problem and to use InStr Public Function GetSQL(strQuery As String, _ Optional blnLoseSC As Boolean = True) As String Dim intDepth As Integer Dim lngLeft As Long, lngOpen As Long, lngRight As Long, lngAdjust As Long 'If param passed is already SQL then leave as is - Otherwise get from query If Left(strQuery, 1) = "(" Then GetSQL = strQuery Else On Error Resume Next GetSQL = CurrentDb.QueryDefs(strQuery).SQL End If lngLeft = -7 Do 'Check for corrupted subquery lngLeft = InStr(lngLeft + 8, GetSQL, " [SELECT ", vbTextCompare) If lngLeft = 0 Then Exit Do 'To find end correctly we must treat '[' & ']' as matched pairs intDepth = 1 lngRight = lngLeft + 8 lngOpen = -lngRight Do 'Find next ']' lngRight = InStr(lngRight + 1, GetSQL, "]", vbBinaryCompare) If lngRight = 0 Then GetSQL = "" Exit Function End If intDepth = intDepth - 1 Do 'For lngOpen negative numbers mean that item has been counted 'If already counted get next one - Otherwise drop through If lngOpen < 0 Then _ lngOpen = InStr(-lngOpen + 1, GetSQL, "[", vbBinaryCompare) 'we're only interested (now) if it found one BEFORE the ']' If lngOpen > lngRight Or lngOpen = 0 Then Exit Do intDepth = intDepth + 1 lngOpen = -lngOpen Loop Loop While intDepth > 0 'If '].' found then be sure to drop the '.' too lngAdjust = IIf(Mid(GetSQL, lngRight + 1, 1) = ".", 1, 0) GetSQL = Left(GetSQL, lngLeft) & "(" & _ Mid(GetSQL, lngLeft + 2, lngRight - lngLeft - 2) & ")" & _ Right(GetSQL, Len(GetSQL) - (lngRight + lngAdjust)) Loop 'Lose ";" at end if requested and it exists If blnLoseSC And Right(GetSQL, 3) = ";" & vbCrLf Then _ GetSQL = Left(GetSQL, Len(GetSQL) - 3) End Function
|
|
July 28th, 2008 07:34 PM
# 26
|
Re: Query Join? Include all records from table
Quote:
Originally Posted by NeoPa
I use the function below when getting SQL from out of a QueryDef.
It's true, there are times in later versions when the square brackets are accepted, but they are not standard SQL even then.
Code: ( text )
'GetSQL gets the SQL component from a named query OR a SQL string. 'When subqueries are specified in MS Access they are changed internally 'from "FROM (SELECT blah blah blah) AS" to 'either "FROM [SELECT blah blah blah]. AS" 'or "FROM [SELECT blah blah blah] AS" both of which are invalid SQL. 'This code assumes any effected subquery will start with " [SELECT ". 'This reverts SQL to correct format and loses ';' at end if requested. ' 11/11/2004 Updated to detect second problem and to use InStr Public Function GetSQL(strQuery As String, _ Optional blnLoseSC As Boolean = True) As String Dim intDepth As Integer Dim lngLeft As Long, lngOpen As Long, lngRight As Long, lngAdjust As Long 'If param passed is already SQL then leave as is - Otherwise get from query If Left(strQuery, 1) = "(" Then GetSQL = strQuery Else On Error Resume Next GetSQL = CurrentDb.QueryDefs(strQuery).SQL End If lngLeft = -7 Do 'Check for corrupted subquery lngLeft = InStr(lngLeft + 8, GetSQL, " [SELECT ", vbTextCompare) If lngLeft = 0 Then Exit Do 'To find end correctly we must treat '[' & ']' as matched pairs intDepth = 1 lngRight = lngLeft + 8 lngOpen = -lngRight Do 'Find next ']' lngRight = InStr(lngRight + 1, GetSQL, "]", vbBinaryCompare) If lngRight = 0 Then GetSQL = "" Exit Function End If intDepth = intDepth - 1 Do 'For lngOpen negative numbers mean that item has been counted 'If already counted get next one - Otherwise drop through If lngOpen < 0 Then _ lngOpen = InStr(-lngOpen + 1, GetSQL, "[", vbBinaryCompare) 'we're only interested (now) if it found one BEFORE the ']' If lngOpen > lngRight Or lngOpen = 0 Then Exit Do intDepth = intDepth + 1 lngOpen = -lngOpen Loop Loop While intDepth > 0 'If '].' found then be sure to drop the '.' too lngAdjust = IIf(Mid(GetSQL, lngRight + 1, 1) = ".", 1, 0) GetSQL = Left(GetSQL, lngLeft) & "(" & _ Mid(GetSQL, lngLeft + 2, lngRight - lngLeft - 2) & ")" & _ &nb
|
| |