I have created a report in Access and I have written a query for fetching records from
multiple tables as follows:
SELECT BuildingDetails.*, Contractors.Item, ActionDetails.ActionType
FROM Contractors
INNER JOIN (BuildingDetails
INNER JOIN (ActionDetails
INNER JOIN DormData ON ActionDetails.ActionID = DormData.ActionID)
ON BuildingDetails.BuildingID = DormData.BuildingID)
ON Contractors.ID = DormData.ItemID;
Now what I want is only actiontype=repair or actionid=1 get retrieved by the query. We have two actontype "repair" and "replace".
I have reformatted you query a little to neaten it up. You haven't specified what the data looks like for the filter but based on what you have said I would go with something like the following
SELECT BuildingDetails.*,
Contractors.Item,
ActionDetails.ActionType
FROM Contractors
INNER JOIN DormData ON Contractors.ID = DormData.ItemID
INNER JOIN ActionDetails ON DormData.ActionID = ActionDetails.ActionID
INNER JOIN BuildingDetails ON DormData.BuildingID = BuildingDetails.BuildingID
WHERE ActionDetails.ActionType = 'Repair' OR ActionID=1
If ActionID is a lookup column that relates ActionID(1) to ActionType ('Repair') then you don't need the or and can stick to one or other of the conditions in the WHERE Clause.
Hope this helps.
I suspect you only need to filter using actiontype = 'repair' (I further guess that ActionID is an autonumber and you have a row {ActionID = 1, actiontype = 'repair'} only by chance... but this is maybe extrapolating too far :)
I'm surprised #David Steele's answer works in Access (ACE, Jet, whatever) because he's removed the parentheses from the JOIN clauses (however if it does -- suggesting a linked table -- then you should "accept" that answer). But I too could resist 'neatening them up' so that the ON clauses are close to the table names:
SELECT BuildingDetails.*, Contractors.Item, ActionDetails.ActionType
FROM ((DormData
INNER JOIN Contractors
ON Contractors.ID = DormData.ItemID)
INNER JOIN BuildingDetails
ON BuildingDetails.BuildingID = DormData.BuildingID)
INNER JOIN ActionDetails
ON ActionDetails.ActionID = DormData.ActionID
WHERE ActionDetails.ActionType = 'repair';
Add this to the end of your select statement to fix the issue:
where actiondetails.actiontype = 'repair' or actiondetails.actionid = 1
Related
New to SQL but I want to be able to optimize my query by bringing just the right amount of data. I am doing a left join on CS Rep Name and WE, which are two columns present in both tables. I find that if I don't bring in CS Rep Name and WE in the TECDR table, the query would error. Is there a workaround to this? Since it is a left join, I don't need redundant data.
SELECT *
FROM Tish_Email_CSAT_Dump AS TECD
LEFT JOIN (SELECT CS_Rep_Name,
Team_Leader,
Operations_Manager,
Tenure,
WE,
FileName
FROM Tish_Email_CSAT_Dump_Roster) AS TECDR
ON TECD.CS_Rep_Name = TECDR.CS_Rep_Name
AND TECD.WE = TECDR.WE
When you embed a SELECT inside a query in place of a table, the result of a select (projection) behave like a table visible only inside the query.
In your case, the join is the same as if there were a table called TECDR with the columns that you select. Hence, if you leave out some columns of Tish_Email_CSAT_Dump_Roster from your SELECT, these columns would not be available for joining or selection.
However, in your case this is unnecessary: all you need to do is joining to the underlying table, like this:
SELECT
TECD.*
, TECDR.Team_Leader
, TECDR.Operations_Manager
, TECDR.Tenure
, TECDR.FileName
FROM Tish_Email_CSAT_Dump AS TECD
LEFT JOIN Tish_Email_CSAT_Dump_Roster AS TECDR
ON TECD.CS_Rep_Name = TECDR.CS_Rep_Name AND TECD.WE = TECDR.WE
select
<place the columns you want here>
from
Tish_Email_CSAT_Dump as TECD
Left join Tish_Email_CSAT_Dump_Roster as TECDR
On TECD.CS_Rep_Name = TECDR.CS_Rep_Name and TECD.WE = TECDR.WE
Hope the following helps or else please share the query that errors:
select TECD.Column1, TECD.Column2, TECDR.Column1, TECDR.Column2
from Tish_Email_CSAT_Dump as TECD
Left join Tish_Email_CSAT_Dump_Roster as TECDR
On TECD.CS_Rep_Name = TECDR.CS_Rep_Name and TECD.WE = TECDR.WE
SELECT
Trs.itemID, Trs.imtName, Trs.sumQty, Sum(whiQty)
FROM
((SELECT
trsitemID AS itemID, trsimtName AS imtName,
Sum(trsQty) As sumQty
FROM
tblTransactionSub AS T
WHERE
trstraID = 1231
AND trsActive = True
GROUP BY
trsitemID, trsimtName) AS Trs
INNER JOIN
tblWarehouseItem AS WHI ON Trs.itemID = WHI.whiitemID)
RIGHT JOIN
WHI ON Trs.trswhiID = WHI.whiID
WHERE
whiActive = True
AND whiCansel = False
AND whiwrhID = 19
GROUP BY
Trs.itemID,Trs.imtName, Trs.sumQty
HAVING
SUM(whiQty) < Trs.sumQty
If you please help me me out since I am new to SQL commands I can not easily find my mistake.
Thanks in advance
The error that occurred when I added the Right Join is:
Join expression not supported
In MS Access, you have to use parenthesises with multiple joins:
select ...
from
((table1
... join table2 on ...)
... join table3 on ...)
... join tableN
/edit/
As OP question changes its syntax often, then my answer seems out of place :) Initially there were no parens there.
About RIGHT JOIN: You need to use table name (or entire subselect) after JOIN keyword, not skip it or use some other alias. Your query part
RIGHT JOIN
WHI ON Trs.trswhiID = WHI.whiID
currently uses alias WHI, which is wrong in two ways: 1) it is not table name 2) it is already used. You need something like this:
RIGHT JOIN
tblWarehouseItem AS WHI2 ON Trs.trswhiID = WHI2.whiID
It could be possible that MS Access restricts your kind of JOINs usage (like INNER join should not come after LEFT join); I have currently no possibility to check precise rules.
Your problem is that you have no table name after the RIGHT JOIN:
RIGHT JOIN
ON Trs.trswhiID = WHI.whiID
Should be:
RIGHT JOIN YOURTABLENAMEHERE as alias
ON Trs.trswhiID = WHI.whiID
However, you have already defined Trs and Whi, so I have no idea what table you want there, or why. Perhaps you just want to change the INNER JOIN to a LEFT JOIN or RIGHT JOIN.
I'm trying to run a query on a table (the one Wordpress uses) where I want to select the ID and post_type columns from one table, then do a Left Join to another table, two separate times (getting separate data).
This is what I have so far, but it's not cutting the mustard:
SELECT derby_posts.id AS pID,
derby_posts.post_type AS tier
FROM derby_posts
LEFT JOIN (SELECT derby_postmeta.post_id AS dbID1,
derby_postmeta.meta_key AS dbMeta1)
ON pid = dbid1
AND dbmeta1 = 'twitter'
LEFT JOIN (SELECT derby_postmeta.post_id AS dbID2,
derby_postmeta.meta_key AS dbMeta2)
ON pid = dbid2
AND dbmeta2 = 'website'
WHERE tier IN ('local', 'regional', 'national')
I'm sure I'm missing something super simple...
Edit: here's the solution that worked for me. Table alias helped, putting all my SELECT statements together cleaned things up. Also, I realized I could remove items from the SELECT, even though I'm using them in the Join, which cleans up the results a lot.
SELECT
db.ID as id,
db.post_type as tier,
dpm1.meta_value as twitter,
dpm2.meta_value as website
FROM derby_posts db
LEFT JOIN derby_postmeta dpm1 ON (db.ID = dpm1.post_id AND dpm1.meta_key = 'twitter' )
LEFT JOIN derby_postmeta dpm2 ON (db.ID = dpm2.post_id AND dpm2.meta_key = 'website' )
WHERE db.post_type IN ('local','regional','national')
I 'm sure I'm missing something super simple...
You are right!
You need to give your selects an alias, and use that alias in the ON clause. You are also missing a FROM <table> - a required part of a SELECT statement that reads from a table:
LEFT JOIN (
SELECT derby_postmeta.post_id AS dbID1,
derby_postmeta.meta_key AS dbMeta1
FROM someTable
) dpm ON pid = dpm.dbid1 AND dpm.dbmeta1 = 'twitter'
I gave the results of your SELECT an alias dpm, and used it to "link up" the rows from the inner select to the rows of your outer select.
SELECT
db.derby_posts.ID as pID,
db.derby_posts.post_type as tier,
dpm1.post_id as dbID1,
dpm1.meta_key as dbMeta1,
dpm2.post_id as dbID2,
dpm2.meta_key as dbMeta2
FROM derby_posts db
LEFT JOIN derby_postmeta dpm1 ON (db.pID = dpm1.post_id AND dpm1.meta_key= 'twitter')
LEFT JOIN derby_postmeta dpm2 ON (db.pID = dbm2.post_id AND dbm2.meta_key = 'website')
WHERE tier IN ('local','regional','national')
I'm replacing a subquery with an self join to improve performance of my query.
The old subquery was like this:
(SELECT fage2.agecat
FROM people AS fage2
WHERE fage2.aacode = people.aacode
AND fage2.persno = 2) AS RAge2,
The new self join is like this:
(SELECT [People].[AgeCat]
FROM [People]
INNER JOIN [People] AS p2
ON [People].[aacode] = [P2].[aacode]
WHERE [P2].[PERSNO] = 2 ) AS RAge2,
but returns a No Current Record error message.
The goal is to find the record that has the same aacode but has the PERSNO number of 2 and return the AgeCat for that record in a column called RAge2,
This is only part of a larger query which is explained in full Convert a SQL subquery into a join when looking at another record in the same table Access 2010
Huum, looks like this query that you want to optimize is part of a bigger query, and would be important to the question that you post the entire query so it would help on understanding your problem ...
Also, from what I can see you would be showing the RAge2 for both rows with same AACode not only to the one that has Persno = 2 as you said on the goal. Pasting your entire query would help to understand that also.
I was trying to understand your query, so I created a fake query for your original one:
SELECT
(SELECT FAge2.AgeCat
FROM People AS FAge2
WHERE FAge2.aacode = People.aacode
AND FAge2.PERSNO = 2) AS RAge2,
People.PersonId
FROM People
To get the same results you would need a Left Join and not a Inner Join as a query with a subquery wouldn't exclude results from the outer table, so you would have something like this as the resulting Join query:
SELECT
FAge2.AgeCat as RAge2,
People.PersonID,
FROM People
Left JOIN People AS FAge2 ON (FAge2.aacode = People.aacode AND FAge2.PERSNO = 2)
Please use:
(SELECT [People].[AgeCat] FROM [People] INNER JOIN [People] AS P2 ON ([People].[aacode] = [P2].[aacode] AND [P2].[PERSNO] = 2)) AS RAge2
Ok.. So I'm trying to improve my SQL skills and have a question. Here is a screen shot of the schema.
Schema http://img509.imageshack.us/img509/97/screenhunter02nov121946.gif
(http://img509.imageshack.us/img509/97/screenhunter02nov121946.gif)
Alright so I'm selecting a bunch of Report Bundles and other rows from a table you can see. I've got these two tables joining together correctly and displaying what should be returned. Now I need to add another field onto my result rows that states what type of report this is. How can I join up to the ReportGroupType table through the ReportBundleGroup table without getting a shwack of results?
Here is the query I am using so far.
SELECT *
FROM ReportBundleCustomerVisibility INNER JOIN ReportBundle
ON ReportBundleCustomerVisibility.ReportBundleID = ReportBundle.ID
WHERE ReportBundleCustomerVisibility.ReferenceCustomerID = 2303
Thanks again SO
SELECT *
FROM ReportBundleCustomerVisibility AS v
JOIN ReportBundle AS b ON b.ID = v.ReportBundleID
JOIN ReportBundleGroup AS g ON b.ID = g.ReportBundleID
JOIN ReportGroupTYpe AS t ON t.ID = g.ReportGroupTypeID
WHERE v.ReferenceCustomerID = 2303
It sounds like you just need another inner join to get the information you need. You can think about the second join as joining the result of the join with the ReportGroupType table. I added parenthesis to try to join the two sets the second INNER JOIN is operating on.
SELECT * FROM ((ReportBundleCustomerVisibility
INNER JOIN ReportBundle ON ReportBundleCustomerVisibility.ReportBundleID = ReportBundle.ID)
INNER JOIN ReportGroupType ON ReportBundleGroup.ReportGroupTypeID = ReportGroupType.ID)
WHERE ReportBundleCustomerVisibility.ReferenceCustomerID = 2303
I also highly suggest against using "SELECT *" in production code or any query you plan on reusing as the table schema can change and possibly effect reports and UI. Explicitly specify the columns instead.