I am using MS Access 2007. Whenever I type Left Join, I get an error that says Left Join is not supported. Here's the SQL
TRANSFORM Count([Letter Status].Customer_ID) AS CountOfCustomer_ID
SELECT Switch(
[Race_1]=1,"White",
[Race_1]=2,"Black",
[Race_1]=3,"Asian",
[Race_1]=4,"Hispanic/Latino",
[Race_1]=5,"American Indian/ Alaskan Native",
[Race_1]=6,"Native Hawaiian or Pacific Islander",
[Race_1]=7,"Multiracial",
[Race_1]=8,"Other",
[Race_1]=9,"Unknown"
) AS Race
FROM Demographics
INNER JOIN (
[Status]
INNER JOIN
Research
ON [Status].Customer_ID = Research.Customer_ID
)
ON (Demographics.ID = [Letter Status].Customer_ID)
AND (Demographics.ID = Research.Customer_ID)
WHERE ((([Status].Count)=1))
GROUP BY [Status].Count, Demographics.Race_1
ORDER BY Research.Store_site
PIVOT Research.Store_site In (1,2,3,4,5,6,7,8,9,10);
Could someone please use the above code to show me where to place the Left Join in order to allow the rows for each Race to show in the table? Also, could you please show me how to replace Null Values with 0 in this code? I have tried to implement NZ() but have been unsuccessful.
Please help.
Look closely at your FROM clause.
FROM Demographics
INNER JOIN (
[Status]
INNER JOIN
Research
ON [Status].Customer_ID = Research.Customer_ID
)
ON (Demographics.ID = [Letter Status].Customer_ID)
AND (Demographics.ID = Research.Customer_ID)
You have an ON condition which refers to [Letter Status], but [Letter Status] isn't included among your source tables .... you do have one called [Status].
Start by building the JOINs in the query designer, so you know you're starting with SQL which Access will accept.
And simplify this thing until you get the JOINs sorted out. Get rid of Switch, TRANSFORM, PIVOT, and GROUP BY until after you have JOINs working.
Related
In my Access database I am trying to display data from three tables:
PERS
COURSE
WORKED
I want all rows from PERS and some matching fields from COURSE and WORKED. KNO is the common field in all tables
eg : SELECT [KNO], [Name], [Company], [Location], [State] FROM [Pers]
If the KNo had done CCNA (Course.Qualification)
if he had Worked in Channai or Kolkatta or in Bangalore (Worked.Coyloc)
then only show
I used :
Select
Pers.KNO, Pers.Name, Pers.Company, Pers.Location, Pers.State
from Pers
left join (Course on pers.KNo=Course.KNO)
left join Worked.KNo=Per.KNO
where
Course.Qualification='CCNA'
and (Worked.Coyloc='Bangalore' or Worked.Coyloc='Channai or Worked.Coyloc='Kolkatta')
I am having trouble adding the [Worked] table to the query. When I just include [Pers] and [Course] I get the results I expect.
Select
Pers.KNO, Pers.Name, Pers.Company, Pers.Location, Pers.State
from Pers
left join Course
on pers.KNo=Course.KNO
where
Course.Qualification='CCNA'
If you are having trouble writing a query sometimes it is helpful to mock it up using the Query Designer in Access and then see what SQL it produces. For your query:
switching to SQL View reveals the following (reformatted for clarity):
SELECT Pers.KNO, Pers.Name, Pers.Company, Pers.Location, Pers.State
FROM
(
Pers
LEFT JOIN
Course
ON Pers.KNO = Course.KNO
)
LEFT JOIN
Worked
ON Pers.KNO = Worked.KNO
WHERE (((Course.Qualification)="CCNA") AND ((Worked.Coyloc)="Bangalore"))
OR (((Course.Qualification)="CCNA") AND ((Worked.Coyloc)="Channai"))
OR (((Course.Qualification)="CCNA") AND ((Worked.Coyloc)="Kolkatta"));
Note that the parentheses in the FROM clause are important. Access is a bit fussy about that.
Other notes:
As you may have noticed, the WHERE clause could be reorganized as
WHERE Course.Qualification="CCNA"
AND (Worked.Coyloc="Bangalore" OR Worked.Coyloc="Channai" OR Worked.Coyloc="Kolkatta")
Also, since you have specific WHERE conditions on columns in both the [Course] and [Worked] tables then you don't really need to use LEFT JOINs. INNER JOINs would have sufficed.
I'm new to sql and trying to tweak someone else's huge stored procedure to get a subset of the results. The code below is maybe 10% of the whole procedure. I added the lp.posting_date, last left join, and the where clause. Trying to get records where the posting date is between the start date and the end date. Am I doing this right? Apparently not because the results are unaffected by the change. UPDATE: I CHANGED THE LAST JOIN. The results are correct if there's only one area allocation term. If there is more than one area allocation term, the results are duplicated for each term.
SELECT Distinct
l.lease_id ,
l.property_id as property_id,
l.lease_number as LeaseNumber,
l.name as LeaseName,
lty.name as LeaseType,
lst.name as LeaseStatus,
l.possession_date as PossessionDate,
l.rent as RentCommencementDate,
l.store_open_date as StoreOpenDate,
msr.description as MeasureUnit,
l.comments as Comments ,
lat.start_date as atStartDate,
lat.end_date as atEndDate,
lat.rentable_area as Rentable,
lat.usable_area as Usable,
laat.start_date as aatStartDate,
laat.end_date as aatEndDate,
MK.Path as OrgPath,
CAST(laa.percentage as numeric(9,2)) as Percentage,
laa.rentable_area as aaRentable,
laa.usable_area as aaUsable,
laa.headcounts as Headcount,
laa.area_allocation_term_id,
lat.area_term_id,
laa.area_allocation_id,
lp.posting_date
INTO #LEASES FROM la_tbl_lease l
INNER JOIN #LEASEID on l.lease_id=#LEASEID.lease_id
INNER JOIN la_tbl_lease_term lt on lt.lease_id=l.lease_id and lt.IsDeleted=0
LEFT JOIN la_tlu_lease_type lty on lty.lease_type_id=l.lease_type_id and lty.IsDeleted=0
LEFT JOIN la_tlu_lease_status lst on lst.status_id= l.status_id
LEFT JOIN la_tbl_area_group lag on lag.lease_id=l.lease_id
LEFT JOIN fnd_tlu_unit_measure msr on msr.unit_measure_key=lag.unit_measure_key
LEFT JOIN la_tbl_area_term lat on lat.lease_id=l.lease_id and lat.isDeleted=0
LEFT JOIN la_tbl_area_allocat_term laat on laat.area_term_id=lat.area_term_id and laat.isDeleted=0
LEFT JOIN dbo.la_tbl_area_allocation laa on laa.area_allocation_term_id=laat.area_allocation_term_id and laa.isDeleted=0
LEFT JOIN vw_FND_TLU_Menu_Key MK on menu_type_id_key=2 and isActive=1 and id=laa.menu_id_key
INNER JOIN la_tbl_lease_projection lp on lp.lease_projection_id = #LEASEID.lease_projection_id
where lp.posting_date <= laat.end_date and lp.posting_date >= laat.start_date
As may have already been hinted at you should be careful when using the WHERE clause with an OUTER JOIN.
The idea of the OUTER JOIN is to optionally join that table and provide access to the columns.
The JOINS will generate your set and then the WHERE clause will run to restrict your set. If you are using a condition in the WHERE clause that says one of the columns in your outer joined table must exist / equal a value then by the nature of your query you are no longer doing a LEFT JOIN since you are only retrieving rows where that join occurs.
Shorten it and copy it out as a new query in ssms or whatever you are using for testing. Use an inner join unless you want to preserve the left side set even when there is no matching lp.lease_id. Try something like
if object_id('tempdb..#leases) is not null
drop table #leases;
select distinct
l.lease_id
,l.property_id as property_id
,lp.posting_date
into #leases
from la_tbl_lease as l
inner join la_tbl_lease_projection as lp on lp.lease_id = l.lease_id
where lp.posting_date <= laat.end_date and lp.posting_date >= laat.start_date
select * from #leases
drop table #leases
If this gets what you want then you can work from there and add the other left joins to the query (getting rid of the select * and 'drop table' if you copy it back into your proc). If it doesn't then look at your Boolean date logic or provide more detail for us. If you are new to sql and its procedural extensions, try using the object explorer to examine the properties of the columns you are querying, and try selecting the top 1000 * from the tables you are using to get a feel for what the data looks like when building queries. -Mike
You can try the BETWEEN operator as well
Where lp.posting_date BETWEEN laat.start_date AND laat.end_date
Reasoning: You can have issues wheres there is no matching values in a table. In that instance on a left join the table will populate with null. Using the 'BETWEEN' operator insures that all returns have a value that is between the range and no nulls can slip in.
As it turns out, the problem was easier to solve and it was in a different place in the stored procedure. All I had to do was add one line to one of the cursors to include area term allocations by date.
Have tried the below SQL in MS Access but cannot seem to get it working, anyone got a better idea?
SELECT top 4 Student.STUDENT_DEGREE, Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM (((Student)
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;
Whenever i run this i just get the error:
Syntax error in FROM clause
Group is a reserved word. Enclose that name in square brackets to avoid confusing the db engine. You can also assign an alias for the table name.
FROM
(Student
INNER JOIN Result
ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN [Group] AS g
ON Result.RESULT_GROUP_ID = g.GROUP_ID
I had to guess which tables contain those fields in the last ON clause. If you set up the joins in Design View of the Access query designer, it will help you get the names right. It will also add the parentheses which the db engine requires for any query which includes more than one join.
Also qualify the table sources for the field names in your SELECT list and elsewhere in the query. Here again, the query designer can supply the correct names for you.
Remove the extra set of parentheses around Student:
SELECT top 4 Student.STUDENT_DEGREE,Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM ((Student
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;
Disclaimer - My knowledge of SQL Server is limited. So I apologize in advance if this is a 'dumb' question.
Purpose of query - gathering information from a multi-table database from a program our company uses and depositing the results into our web database so we can display some of the information.
Issue - duplicate information. Part of the issue is that there are multiple instances of people in the database, so there are results duplicated that way... and the other duplicates come from the join. I need to combine the results so that I deposit just one result with the same Name or Code (ID). The rest of the information I would like to combine so that I don't lose any information that may be needed.
Here is query I have:
SELECT people.Code AS [athlete-id],
people.Name AS [athlete-name],
people.DOB AS [DOB],
people.Division AS [agency-id],
certifs.[Expiration date] AS [expiration-date],
groups.Name AS [agency-name],
address.Addresses AS [address],
address.City AS [city],
address.State AS [state],
case when tags.Field = 'ABJD86GHKXXQWA9Q'
then tags.Value
end AS [restrictions],
case when tags.Field = 'VH2C78N9A15S059T'
then tags.Value
end AS [comments]
FROM people
LEFT OUTER JOIN certifs
ON people.Code = certifs.Owner
LEFT OUTER JOIN groups
ON people.Division = groups.Code
LEFT OUTER JOIN address
ON people.Code = address.Owner
LEFT OUTER JOIN tags
ON people.Code = tags.Owner
ORDER BY [agency-name], [athlete-name]
Let me know of any questions you may have. I appreciate the help.
How about if you insert DISTINCT right after SELECT and before people.Code ?
SELECT DISTINCT
people.Code [...]
I have a cross tab query that looks like this:
State Building 1 2 3 4 5
NY
SC
FL
The problem I am having is that I want all of the states to show up, regardless of whether or not there is data. So, I need a Left Join. Unfortunately, when I substitute the Inner Join for Left Join in the code, nothing changes. I am just trying to figure out where the problem is coming from, and I think it may be one of the following causes:
The query doesn't know where to pull
the values from (The states are all
listed in a look up but this may
not be where it's looking)
Left Joins don't work on cross tab
queries.
Could someone please tell me what I am doing wrong?
Here's the SQL:
TRANSFORM Nz(Count(Demographics.ID))+0 AS CountOfID
SELECT Demographics.State
FROM Research
INNER JOIN ( Demographics
INNER JOIN [Status]
ON Demographics.ID=[Status].ID
)
ON (Research.ID=Demographics.ID)
AND (Research.ID=[Status].ID)
WHERE ((([Status].Building_Status)='Complete'))
GROUP BY Demographics.State,
[Status].Building_Status
PIVOT Research.Site In (1,2,3,4,5,6,7,8,9,10,11)
Ideally, I could specify the row values in the In statement above (which is currently specifying column values 1-10), but I don't think this can be done.
I didn't completely get your example, but from your comment "I want all of the states to show up, regardless of whether or not there is data", I think you want an "OUTER" join. Outer joins do just that -- they include data regardless of whether or not there is a "match". Inner joins (the default) include data only if there is a match.
Hope this helps,
John
You should change it this way:
TRANSFORM Nz(Count(Demographics.ID))+0 AS CountOfID
SELECT Demographics.State
FROM Demographics
LEFT JOIN ( Research
LEFT JOIN [Status]
ON Demographics.ID=[Status].ID
)
ON (Research.ID=Demographics.ID)
AND (Research.ID=[Status].ID)
WHERE ((([Status].Building_Status)='Complete'))
GROUP BY Demographics.State,
[Status].Building_Status
PIVOT Research.Site In (1,2,3,4,5,6,7,8,9,10,11)
If your problem is that there may be 0 rows in table Demographics with State = 'NY' (for example) but you want to see state 'NY' in the results anyway, then you need another table e.g. States that has all the states in it, and make this your driving table:
SELECT States.State
FROM States
LEFT OUTER JOIN Demographics ON Demographics.state = States.state
...
you can use a two steps solution (it is more readable)
first enclose your actual (and working) sql statment as a view
create view step1 as
TRANSFORM ....
SELECT ...
FROM ...
PIVOT ...
and then create a select like:
(you will need a state table like #Tony Andrews says)
select * -- or whatever
from state
left join step1 on state.id = step1.state
and that's all