To start off, I would classify myself as a relatively new MS Access user (had to teach myself for work) and have encountered a problem. I have a cross-tab query (code displayed below) with the resulting datasheet resembling the desired results picture attached (excluding the % of total column). I would like to be able to reference the Sum total from the Total Spend row in all three of the % of total columns. This has proven to be a harder task than I initially had thought.
TRANSFORM Sum(Table1.Amount) AS SumOfAmount
SELECT tblSpendCat.SPEND_CAT, tblSpendCat.SPEND_DESC, Sum(Table1.Amount) AS Totals
FROM tblSpendCat INNER JOIN (tblType INNER JOIN (tblOrg INNER JOIN Table1 ON tblOrg.ID = Table1.tblORG_ID) ON tblType.ID = Table1.tblType_ID) ON tblSpendCat.ID = Table1.tblSpendCat_ID
WHERE (((tblSpendCat.SPEND_CAT)="Total_Spend" Or (tblSpendCat.SPEND_CAT)="Supplies" Or (tblSpendCat.SPEND_CAT)="Other Costs" Or (tblSpendCat.SPEND_CAT)="Misc") AND ((Table1.mnth)>"April") AND ((tblOrg.Org)="Org1" Or (tblOrg.Org)="Org2" Or (tblOrg.Org)="Org3" Or (tblOrg.Org)="Org4" Or (tblOrg.Org)="Org5" Or (tblOrg.Org)="Org6" Or (tblOrg.Org)="Org7"))
GROUP BY tblSpendCat.SPEND_CAT, tblSpendCat.SPEND_DESC
PIVOT Table1.mnth;
What I have tried:
I queried the specific Total Spend value in a separate stand-alone query and attempted to reference it in the main cross-tab query in a new expression field: results returned from the separate, stand-alone query :
Tried referencing the calculated value directly from the main cross-tab query (the same main cross-tab query referenced in this post) in a new expression field in the same main cross-tab query
Desired Results:
Thanks in advance for any help!
Best,
James
Related
I have got a somewhat complicated problem. This is my situation (ERD).
For a dashboard i need to create a pivot table that shows me the total amount of competences used by the vacancies. Therefore I need to:
Count the amount of vacancies per template
Count the amount of templates per competence
and last: multiply these numbers to get the total amount of comps used.
I have the first query:
SELECT vacancytemplate_id, count(id)
FROM vacancies
group by vacancytemplate_id;
And the second query isn't that difficult either, but I don't know what the right solution will be. I'm literally brainstuck. My mind can't comprehend how I can achieve the next step and put it down in a query. Please kind stranger, help me out :)
EDIT: my desired result is something like this
NameOfComp, NrOfTimesUsed
Leading, 17
Inspiring, 2
EDIT2: the meta query it should look like:
SELECT NameOfComp, (count of the competences used by templates) * (number of vacancies per template)
EDIT3: http://sqlfiddle.com/#!9/2773ca SQLFiddle
Thanks a lot!
If I am understanding your request correctly, you are wanting a count of competences per vacancy. This can be done very simply due to your table structure:
Select v.ID, count(*) from vacancy as v inner join CompTemplate_Table as CT
on v.Template_ID = CT.Template_ID group by v.ID;
The reason you can do only one join is because there will be a record in the CompTemplate_Table for every competency in each template. Additionally, the same key is used to join vacancy to templates as is used to join templates to CompTemplate_Table, so they represent the same key value (and you can skip joining the Templates table if you don't need data from there).
If you are wanting to add this data to a pivot table, I will leave that exercise to you. There are a number of tutorials available if you do a quick google search and it should not be that hard.
UPDATE: For the second query you are looking at something like:
Select cp.NameOfComp, count(*) from vacancy as v inner join CompTemplate_Table as CT
on v.Template_ID = CT.Template_ID inner join competencies as CP
on CP.ID = CT.Comp_ID
group by CP.NameOfComp
The differences here are you are adding in the comptetencies table, as you need data from that, and grouping by the CP.NameOfComp instead of the vacancy id. You can also restrict this to specific templates, competencies, or vacancies by adding in search conditions (e.g. where CP.ID = 12345)
Good day,
I am trying to join 3 tables for my inventory report but I am getting weird results out of it.
my query
SELECT i_inventory.xid,
count(x_transaction_details.xitem) AS occurrence,
i_inventory.xitem AS itemName,
SUM(i_items_group.or_qty) AS `openingQty`,
avg(x_transaction_details.cost) AS avg_cost,
SUM(x_transaction_details.qty) AS totalNumberSold,
SUM(i_items_group.or_qty) - SUM(x_transaction_details.qty) AS totalRemQty
FROM x_transaction_details
LEFT JOIN i_inventory ON x_transaction_details.xitem = i_inventory.xid
LEFT JOIN i_items_group ON i_inventory.xid = i_items_group.xitem
WHERE (x_transaction_details.date_at BETWEEN '2015-01-18 03:14:54' AND '2015-10-18 03:14:54')
AND i_inventory.xid = 3840
GROUP BY x_transaction_details.xitem
ORDER BY occurrence DESC
This query gives me this result:
See the openingQty column, I then tried to do a simple query to verify the result,
here's my query for checking the openingQty with joining only 2 tables i_items_group table (batches are stored) and i_inventory table (item Information are stored).
SELECT i_inventory.xid,
i_inventory.xitem,
SUM(i_items_group.or_qty) AS openingQty,
i_items_group.cost
FROM i_inventory
INNER JOIN i_items_group ON i_inventory.xid = i_items_group.xitem
WHERE i_inventory.xid = 3840
AND (i_items_group.date_at BETWEEN '2015-01-18 03:14:54' AND '2015-10-18 03:14:54')
my result was:
which is the correct data.
I also made a query on my x_transaction_details table also to verify if its correct or not.
heres my query:
select xitem, qty as qtySold from x_transaction_details where xitem = 3840
AND (date_at BETWEEN '2015-01-18 03:14:54' AND '2015-10-18 03:14:54')
result:
Which would total to: 15-quatitySold.
I'm just confused on how did I get 3269 as a result of my query where as the true openingQty should be only 467.
I guess the problem was in my query with joins, its messing up with number of transactions then it sums it up (I really dont know though).
Can you please help me identify it, and help me come up with the correct query.
This is a common problem with multiple SUM statements in a single query. Keep in mind how SQL does aggregation: first it generates a set of data that is not aggregated, then it aggregates it. Try your query without the GROUP BY or aggregate functions, and you'll be surprised what you turn up. There aren't enough of the right details in your post for me to determine where the breakdown is, but I can guess.
It looks like you have an xitem corresponding to some kind of product, then you have joined that to both transactions and items groups. Suppose a particular xitem matches with 3 transactions and 5 item groups. You'll get 15 records from that join. And when you sum it, any SUM calculations based on fields from the transaction table will be 5x higher than you expect, and any SUM calculations from the item groups table will be 3x higher than you expect. The key symptom here is the aggregate result being a multiple of the correct value, but seemingly different multiples for different rows.
There are multiple ways to address this kind of error. Some developers like to calculate one of hte aggregates in a subquery, then do the other aggregate in the main query and group by the already correct result from the subquery. Others like to write in-line queries to do the aggregate right in the expression:
SELECT xitem, (SELECT SUM(i_items_group.or_qty) FROM i_items_group WHERE i_inventory.xid = i_items_group.xitem) AS `openingQty`
, -- select more fields
Find what approach works best for you. But if you want to see the evidence for yourself, run this query with the aggregates gone and you'll see why those SUMs are doing what they are doing:
SELECT i_inventory.xid,
x_transaction_details.xitem AS occurrence,
i_inventory.xitem AS itemName,
i_items_group.or_qty,
x_transaction_details.cost,
x_transaction_details.qty,
i_items_group.or_qty - x_transaction_details.qty AS RemainingQty
FROM x_transaction_details
LEFT JOIN i_inventory ON x_transaction_details.xitem = i_inventory.xid
LEFT JOIN i_items_group ON i_inventory.xid = i_items_group.xitem
WHERE (x_transaction_details.date_at BETWEEN '2015-01-18 03:14:54' AND '2015-10-18 03:14:54')
AND i_inventory.xid = 3840
ORDER BY occurrence DESC
wall_paths (table)
wall_dimensions
dimensions (reference table)
What I've got so far:
Query
SELECT wall_paths.wall_id, wall_paths.wall_path,
dimensions.width, dimensions.height
FROM wall_paths
LEFT JOIN wall_dimensions
ON wall_paths.wall_id = wall_dimensions.wall_id
LEFT JOIN dimensions
ON wall_dimensions.dimension_id = dimensions.dimension_id
WHERE wall_paths.wall_id = 4;
Result
The query is selecting redundant rows, I just would like to select the two paths along with the corresponding dimensions based on the wall_dimensions table. Something like below:
Expected result
Result with GROUP BY in query
Please help on how to select something like the above.
Note: I've tried DISTINCT as well on the query but returns an error.
The query results are as expected, actually. Makes sense when you see it, data-wise. The data model is setup incorrectly for this query.
Fiddle (original data model): http://sqlfiddle.com/#!2/8c1bf/1
Fiddle (modified data model): http://sqlfiddle.com/#!2/3d9b0/5
Not saying you should change your model, just pointing out the query runs as expected with the current schema.
Ok - I'm rewording my question in hopes of getting as response. I (with help from a co-worker) have created the following SQL query that pulls the EXACT results that I need to appear in an SSRS chart:
select
(SELECT pfsp.SavingsGoal
FROM Projects AS p INNER JOIN
Projects_PerformanceServicesProject AS pfsp ON p.Id = pfsp.Id INNER JOIN
ProjectSavingsGoalTypes AS gt ON pfsp.ProjectSavingsGoalType_Id = gt.Id
WHERE (p.Id = #Project_ID)) as SavingsGoal,
(SELECT
Sum(identifiedSum)
FROM #Yaks where UPPER(name) = 'DECLINED'
GROUP BY name)as IdentifiedDeclined,
(SELECT
Sum(identifiedSum)
FROM #Yaks) as identifiedTotal,
(SELECT
Sum(implementableSum)
FROM #Yaks where upper(name) = 'APPROVED'
GROUP BY name) as implementableSavingsApproved,
(SELECT
Sum(implementedSum)
FROM #Yaks
) as implementedSavingsTotal
What the chart should ultimately look like (generally speaking):
http://i1365.photobucket.com/albums/r745/twarden11/chart_mockup_zps22cfdbf3.png
Telling you everything I've tried would take all my characters, and would be good for a laugh, and that's about it. It was also be futile, as I am an extreme novice (this is my first time to build a chart - ever, please be clear and speak in non-technical terms when possible), and my efforts I can assure had nothing to do with what I need to be trying.
So what I need are plain instructions on how to turn this query into the table graphic that I've included. I can't express how desperate I am at this point. My co-worker said it would be easier to simply pull the exact data that I need in the query, but never told me how to convert the query to a chart.
Thanks so much.
I would redesign the SQL query to return 2 columns and 5 rows. The 1st column would describe the category e.g. Goal, Identified etc. The 2nd column would present the $ values.
This would probably require a series of SELECT ... UNION ALL ... clauses, one for each of the 5 rows required.
Then I would add the 1st column to the chart as the Category Group, and the 2nd column as the Values (series).
Similar to this question, but their problem with the query was never fully solved:
#Error showing up in multiple LEFT JOIN statement Access query when value should be NULL
I get #Error when I'm expecting to see a Null when doing a left join where there is no corresponding record on the right hand side of the join:
Chain CasesPerMonthPerStore MonthOfFirstOrder
Naturally 2.3 5/1/2011
Tom's Market #Error
Livingstons #Error
EverClear 3.1 7/1/2012
Bob's Market 2.66 5/1/2012
Andy's Exports #Error
Jamestowns 0.89 7/1/2012
It works fine if I copy the data into a table and left join to this table, so I assume there is something wrong in the syntax of the query:
SELECT
MonthRange.Chain,
MonthRange.CasesShipped/IIf(MonthsSinceFirstOrder.Months>DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1,
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1,
MonthsSinceFirstOrder.Months)/NumStores.NumberOfStores AS CasesPerMonthPerStore,
MonthsSinceFirstOrder.MonthOfFirstOrder
FROM
QueryDates,
(
MonthRange
INNER JOIN
NumStores
ON MonthRange.Chain=NumStores.Chain
)
INNER JOIN
MonthsSinceFirstOrder
ON MonthRange.Chain=MonthsSinceFirstOrder.Chain;
This SQL returns the correct results, it's just its behaviour when Left Joining to it that is returning #Errors.
nb the strange Iif statement in the middle checks to see if the number of months since the first order is greater than the number of months included in the specified date range - so if the date range has 6 months and the first order was 9 months before the end date, it uses 6; if the first order was only 4 months before the end date, it uses 4.
-- EDIT UPDATE --
Right, I took elements of the query out one by one, and this is the simplest I can get whilst still recreating the left joining error:
SELECT
MonthRange.Chain,
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore
FROM
QueryDates,
MonthRange;
And this is how I'm left joining to it:
SELECT
Chains.Chain,
ErrorQuery.CasesPerMonthPerStore
FROM
Chains
LEFT JOIN
ErrorQuery
ON Chains.Chain=ErrorQuery.Chain;
Does anything in this SQL look wrong?
While the query should return Null based on the join type, as Allen Browne states in his article, Bug: Outer join expressions retrieved wrongly,
"Instead, it behaves as if [the JET query optimizer] is evaluating the expression after it has returned the results from the lower-level query."
Consequently, you must select the calculated field using an expression that will evaluate to Null if the right-side of the join doesn't match the left-side.
Using your pared-down code as an example:
SELECT
Month.Chain,
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore
FROM
QueryDates,
MonthRange;
SELECT
Chains.Chain,
IIf(IsNull(ErrorQuery.Chain),Null,ErrorQuery.CasesPerMonthPerStore)
FROM
Chains
LEFT JOIN
ErrorQuery
ON Chains.Chain=ErrorQuery.Chain;
It's looking like it could be to do with a known bug in Access, whereby it makes mistakes on outer joins with calculated fields:
http://allenbrowne.com/BugOuterJoinExpression.html
and
http://allenbrowne.com/bug-10.html
So going to see if I can rejig the subqueries to disguise the calculated fields somehow.
I love Access. :)
This is old, but I found a work around that I hope helps somebody. I had the same issue with a right-side query, but I also had a parallel right-side query with a similar data source and derivation that was working correctly in a left join. The difference was there was a UNION query between the working right-side and an underlying query with a simple calculated field. So I put a UNION query between the troublesome right-side query and the final query by creating an empty table with the same fields creating a union with that table and the original right-side query. Worked well. Based on the information from Wilskt and Allen Browne, I think that the UNION is forcing Jet to delay evaluation.