SumIIF Access Query - ms-access

I am struggling to get the desired results i need using an Access query, and was wondering if what i was looking to do was actually achievable in one query, or whether i would need two queries and then export to Excel and interrogate the results there.
I've a table with a number of columns, i am specifically looking at three columns
Row Type - this will either be populated with A or U
Account Number - there will be potentially multiple instances of account number within the table. Although only once against row type "A", and multiple on row type "U"
Value - a currency field. At Account number level, the sum of "U" row, should equal the "A" value
I am looking to produce a query that will list three things.
[Account Number]
Sum of [Value] when [RowType] = "U"
[Value] when [RowType] = "A"
Would i need to create a new column in my table to generate a value for the requirement "Sum of Value when 'U')
I've tried
SUM(IIF([ROWTYPE]='U',[Value],0)) - but that doesn't seem to work.
I've also tried to use the builder within the Query to replicate the same, but again that also doesn't seem to work.
If all else fails i'm content to have to run two queries in Access and then join Excel, but i tihnk for my own learning and knowledge it would be good to know if what i am trying to do is possible.
I was hoping this is possible to compile in Access, but my knowledge of the application is seriously lacking, and despite looking on the MS Access support pages, and also some of the response on the StackOverflow forums, i still can't get my head around what i need to do.
Example of the data
Row Type
Account ID
Value
A
123456789
50.00
U
123456789
30.00
U
123456789
20.00
A
987654321
100.00
U
987654321
80.00
U
987654321
20.00
The data has been loaded into Access, table called "TEST"
This is the SQL i've got, but doesn't give me the desired results.
SELECT [TEST].[ROW TYPE], SUM([TEST].[VALUE]) AS [TEST].[ACCOUNT ID]
FROM [TEST]
GROUP BY [TEST].[ROW TYPE], [TEST].[ACCOUNTID]
When the query generates, would hope to see two rows, one for each account number.
Three row -
Account Number
Sum Value (where row is U)
Value (Where row is A)
I currently get 4 rows in the query. Two results for each account number, one result is the Value when Row Type = A, the other when Row Type = U.

I guess this is what you are after:
SELECT
[Account ID],
Sum(IIf([Row Type]="A",[Value],0)) AS A,
Sum(IIf([Row Type]="U",[Value],0)) AS U
FROM
TEST
GROUP BY
[Account ID];
Output:
Account ID
A
U
123456789
50,00
50,00
987654321
100,00
100,00

Related

How to Combine Fields from Two Datasets SSRS?

I am working on a report to show the total number of hours an employee spent working. Our company tracks labor hours by Service Request and Work Order so I need to bring totals for each into the report.
I created two datasets- one for Work Orders and one for Service Requests. Ideally, I would like to combine the total number of Work Order hours with the total number of Service Request hours and present that number listed by employeeID since both datasets have the employeeID field.
I thought it would be as simple as:
=(SUM(Fields!TOTALHOURS_WO.Value, "DataSet1") + SUM(Fields!TOTALHOURS_SR.Value, "DataSet2"))
I don't get an error, however, I am getting a number which repeats for each employee so I know I'm doing something wrong.
Any help is greatly appreciated.
Mal,
As #StevenWhite mentioned, LOOKUP is probably the function you are looking for.
Here is an example for you. For the example datasets:
EmployeeID | TOTALHOURS_WO
-----------------------------------
123 | 12
456 | 3
EmployeeNum| TOTALHOURS_SR
-----------------------------------
123 | 2
456 | 5
You will note that each table in a SSRS report needs a DataSet assigned to it. I will assume your table is using our first DataSet, which we will name "DataSet1". The second dataset above will be "DataSet2".
For your total hours you will use an expression. It should look something like this:
=TOTALHOURS_WO + LOOKUP(Fields!EmployeeID.Value, Fields!EmployeeNum.Value, Fields!TOTALHOURS_SR.Value, "DataSet2")
So you will be adding the TOTALHOURS_WO from your local dataset to the result from the LOOKUP function. What lookup is doing is taking the first field from your local dataset, finding a match in the dataset provided to the function (as a string), and returning the field from the row it matched to. The last parameter is the dataset to search.
Just in case you get an error... it's always a good idea to cast data to the type you want to work with in case it comes in wrong. So...
=CINT(TOTALHOURS_WO) + CINT(LOOKUP(Fields!EmployeeID.Value, Fields!EmployeeNum.Value, Fields!TOTALHOURS_SR.Value, "DataSet2"))
This assumes you have a one to one match on employee ID. If you have to SUM both fields you can try this:
=SUM(CINT(TOTALHOURS_WO)) + SUM(LOOKUPSET(Fields!EmployeeID.Value, Fields!EmployeeNum.Value, CINT(Fields!TOTALHOURS_SR.Value), "DataSet2"))
SUM for TOTALHOURS_WO will give you the SUM in your current table group (so make sure you are grouping by staff ID in the table). It will then add it to the SUM of LOOKUPSET. LOOKUPSET works the same as lookup but returns an array of matches instead of the first.
Hope this helps.

How to select two MySQL rows and then compare a column and return an output

I've a table with a structure something like this,
Device | paid | time
abc 1 2 days ago
abc 0 1 day ago
abc 0 5 mins ago
Is it possible to write a query that checks the paid column on all the rows where Device = abc and then outputs the most recent two rows that different. Basically, something like an if statement saying if row 1 = 1 and row 2 = 0 output that but only if it's the most recent two columns that are different. For example, in this case, the first and second row. The table is being updated whenever a user changes from a free to paid account etc. It is also updated in different columns for different reasons hence the duplicate 0s for example.
I know this would probably be done better by having another table altogether and updating that every time the user switches account type, but is there any way to make this work?
Thanks
Example:
http://rextester.com/MABU7860 need further testing on edge cases but this seems to work.
SELECT A.*, B.*
FROM SQLfoo A
INNER JOIN SQLFoo B
on A.Device = B.Device
and A.mTime < B.mTime
WHERE A.Paid <> B.Paid
and A.device = 'abc'
ORDER BY B.mTime Desc, A.MTime Desc
LIMIT 1
By performing a self join we on the devices where the time from one table is less than the time from the next table (thus the two records will never matach and we only get the reuslts one way) and we order by those times descending, the highest times appear first in the result since we limit by a single device we don't need to concern ourselves with the devices. We then just need compare the paid from one source to the paid in the 2nd source and return the first result encountered thus limit 1.
Or using user variables
http://rextester.com/TWVEVX7830
in other engines one might accomplish this task by performing the join as in above, assigning a row number partitioned by the device and then simply return all those row_numbers with a value of 1; which would be the earliest date discrepency.
Use LIMIT to limit the number of record on mysql:
http://www.mysqltutorial.org/mysql-limit.aspx
In your case, use LIMIT 2
and then put the 2 record that you just select into an array, then compare the array if the value is different. If they are different then print

FileMaker - Total SubSummary Values

I have a table with records each representing an appointment. I have the name of the contactthe appointment is with, and the date. In another table I have a field that contains how many appointments each contact is supposed to have during the day. There are 12 entries for each contact, because some are expected to have different numbers during different months.
I am able to call up the data for the appropriate contactfor the appropriate month. It looks great in the graph when I count up the number of entries for Contact A and put next to it the expected number of entries from the related table.
The problem I'm running into now is that I need to add up all of the expected appointments between all of the entities. So:
::ContactName:: ::appointments:: ::expected::
Contact A 12 10
Contact B 33 34
Contact C 18 27
Getting the roll up for the actual appointments is easy, a simple COUNT summary field in a subsubsummary section. But what of the expected? Because ContactA had 12 appointments that means that there will be 12 records for them, so putting a summary field for the expected column is would return 120 for all Contact A's. Instead, given the dataset above, I need the calculation to return 71. Does this issue make sense? Any help would be greatly appreciated.
If I am following this correctly, you need to divide the amount of expected appointments between the entries of the group, then total the result. So something like:
Sum ( Entities::Expected ) / GetSummary ( sCount ; EntityID )
(this would be easier if we knew the names of your tables and fields).
P.S. The term "entity" has a specific meaning in the context of a relational database. Consider using another term (e.g. "contacts").
Added:
Using your example data, you should see the following results in the above calculation field:
in the 1st group of 12 records: 10 / 12 = .8333333333333333
in the 2nd group of 33 records: 34 / 33 = 1.0303030303030303
in the 3rd group of 18 records: 27 / 18 = 1.5
When you sum all this up (using a summary field defined as Total of this calculation field), you should get 71 (or a number very near 71, due to rounding errors).
Note: in the above calculation, sCount is a summary field defined in the Appointments table as Count of [ any field that cannot be empty ], and EntityID is the field by which your records are sorted and grouped (and it must be a local field).

Populating with '0' when Data in SSRS Does not exist

I'm trying to create a report in SSRS where I have a matrix, which has gender as the column headings and specifically defined agegroups as the rows. The report is sorted by date (ie, the records being displayed are filtered by the modifedAt value). My problem is that i wish for all of the age group categories to be displayed, even if the dataset does not return any data for that row.
So, for example, if i set the date to be a date where there are no db rows where there are Age5-16 children in - I still want to display the category name, but just have the cells related to that row to display '0'. Instead, the report just drops the whole row because, obviously the query returns no data.
Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together? I'm stuck here so any help is appreciated!
I can think of a few ways to do this:
DataSet level
Instead of just returning the relevant data in the underlying data in the DataSet, include all the categories you want to display in all cases.
e.g. For a database query it might be the difference between an inner and left join, i.e. going from something like:
select *
from AgeGroup
inner join MyData on ...
to:
select *
from AgeGroup
left join MyData on ...
So the report always has all the age groups to display. Where there are NULL values, just display 0.
I think this is the best option if you have control over the DataSet - you won't have to update your report at all, with luck the actual DataSet changes should be minimal, there is still only one DataSet call, and it's by far the simplest to maintain.
Hard code groups into the report
Here you include a table header row for each group you want to display, so these are always displayed in all cases.
Here you have some sort of conditional expression to display the values, e.g. For each group row it will be tailored to that group:
=Sum(IIf(Fields!AgeGroup.Value = "5-16", Fields!Amount.Value, Nothing)
This is not too flexible and will need updates as you change groups, and doesn't have as many options for layout. There is still only one DataSet call, so that is a plus.
Subreports
You can have a parent DataSet that displays one row for each age group, then embed a subreport in each row that displays the data you want for that row.
This allows you flexibility in layout but it will add complexity to the report(s) and will mean that you make a lot of DataSet calls that could be avoided with other options.
I know this is old, but I wanted to elaborate on Ian's section 1 above using joins at the dataset level. (His answer was super helpful to me for a report I'm working on.)
per op:
Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together?
That is how I've handled it successfully, but you can do so without actually creating a separate dataset by using common table expressions (or temp tables, of course).
For these example tables:
AGE_Table
ID Group Group_Desc Toys
1 A 00-10 Teddy Bear
2 B 11-20 Video Game
3 C 21-30 Sports Car
4 D 31-40 Mansion
5 E 41-50 Jewelry
People_Table (filtered for whatever date)
ID Name Age Gender Age_Group
1 Ariel 07 F A
2 Brandon 23 M C
3 Chelsea 27 F C
4 Derek 06 M A
You want to see 2 results for the 00-10 row, 2 for the 21-30 row, and then still see rows for the other age groups even if there aren't any results.
We want to create a dataset with all the different age groupings and then join on it. Behold a solution using common table expressions:
with CTE_Age AS
(SELECT Distinct Age_Group from AGE_Table)
SELECT ID, Name, Age, Gender, CTE_Age.Age_Group FROM People_Table
RIGHT JOIN CTE_Age ON
People_Table.Age_Group = CTE_Age.Age_Group
This will return:
ID Name Age Gender Age_Group
1 Ariel 7 F A
4 Derek 6 M A
NULL NULL NULL NULL B
2 Brandon 23 M C
3 Chelsea 27 F C
NULL NULL NULL NULL D
NULL NULL NULL NULL E
Once you have that in your dataset, you can change NULL values to 0 on the report builder side -- I think in 2008R2 the default is just blank.

Count a specific value from multiple columns and group by values in another column... in mysql

Hey. I have 160 columns that are filled with data when a user fills a report form out and submit it. A few of these sets of columns contain similar data, but there needs to be multiple instance of this data per record set as it may be different per instance in the report.
For example, an employee opens a case by a certain type at one point in the day, then at another point in the day they open another case of a different type. I want to create totals per user based on the values in these columns. There is one column set that I want to target right now, case type. I would like to be able to see all instances of the value "TSTO" in columns CT1, CT2, CT3... through CT20. Then have that sorted by the employee ID number, which is just one column in the table.
Any ideas? I am struggling with this one.
So far I have SELECT CT1, CT2, CT3, CT4, CT5, CT6, CT7, CT8, CT9, CT10, CT11, CT12, CT13, CT14, CT15, CT16, CT17, CT18, CT19, CT20 FROM REPORTS GROUP BY OFFICER
This will display the values of all the case type entries in a record set but I need to count them, I tried to use,
SELECT CT1, CT2, CT3, CT4, CT5, CT6, CT7, CT8, CT9, CT10, CT11, CT12, CT13, CT14, CT15, CT16, CT17, CT18, CT19, CT20 FROM REPORTS COUNT(TSTO) GROUP BY OFFICER
but it just spits an error. I am fairly new to mysql databasing and php, I feel I have a good grasp but query'ing the database and the syntax involved is a tad bit confused and/or overwhelming right now. Just gotta learn the language. I will keep looking and I have found some similar things on here but I don't understand what I am looking at (completely) and I would like to shy away from using code that "works" but I don't understand fully.
Thank you very much :)
Edit -
So this database is an activity report server for the days work for the employees. The person will often open cases during the day. These cases vary in type, and their different types are designated by a four letter convention. So your different case types could be TSTO, DOME, ASBA, etc etc. So the user will fill out their form throughout the day then submit it down to the database. That's all fine :) Now I am trying to build a page which will query the database by user request for statistics of a user's activities. So right now I am trying to generate statistics. Specifically, I want to be able to generate the statistic of, and in human terms, "HOW MANY OCCURENCES OF "USER INPUTTED CASE TYPE" ARE THERE FOR EMPLOYEEIDXXX"
So when a user submits a form they will type in this four letter case type up to 20 times in one form, there is 20 fields for this case type entry, thus there is 20 columns. So these 20 columns for case type will be in one record set, one record set is generated per report. Another column that is generated is the employeeid column, which basically identifies who generated the record set through their form.
So I would like to be able to query all 20 columns of case type, across all record sets, for a defined type of case (TSTO, DOME, ASBA, etc etc) and then group that to corresponding user(s).
So the output would look something like,
316 TSTO's for employeeid108
I hope this helps to clear it up a bit. Again I am fairly fresh to all of this so I am not the best with the vernacular and best practices etc etc...
Thanks so much :)
Edit 2 -
So to further elaborate on what I have going on, I have an HTML form that has 164 fields. Each of these fields ultimately puts a value into a column in a single record set in my DB, each submission. I couldn't post images or more than two URLs so I will try to explain it the best I can without screenshots.
So what happens is this information gets in the DB. Then there is the query'ing. I have a search page which uses an HTML form to select the type of information to be searched for. It then displays a synopsis of each report that matches the query. The user than enters the REPORT ID # for the report they want to view in full into another small form (an input field with a submit button) which brings them to a page with the full report displayed when they click submit.
So right now I am trying to do totals and realizing my DB will be needing some work and tweaking to make it easier to create querys for it for different information needed. I've gleaned some good information so far and will continue to try and provide concise information about my setup as best I can.
Thanks.
Edit 3 -
Maybe you can go to my photobucket and check them out, should let me do one link, there is five screenshots, you can kind of see better what I have happening there.
http://s1082.photobucket.com/albums/j376/hughessa
:)
The query you are looking for would be very long and complicated for your current db schema.
Every table like (some_id, column1, column2, column3, column4... ) where columns store the same type of data can be also represented by a table (some_id, column_number, column_value ) where instead of 1 row with values for 20 columns you have 20 rows.
So your table should rather look like:
officer ct_number ct_value
1 CT1 TSTO
1 CT2 DOME
1 CT3 TSTO
1 CT4 ASBA
(...)
2 CT1 DOME
2 CT2 TSTO
For a table like this if you wanted to find how many occurences of different ct_values are there for officer 1 you would use a simple query:
SELECT officer, ct_value, count(ct_value) AS ct_count
FROM reports WHERE officer=1 GROUP BY ct_value
giving results
officer ct_value ct_count
1 TSTO 2
1 DOME 1
1 ASBA 1
If you wanted to find out how many TSTO's are there for different officers you would use:
SELECT officer, ct_value, count( officer ) as ct_count FROM reports
WHERE ct_value='TSTO' GROUP BY officer
giving results
officer ct_value ct_count
1 TSTO 2
2 TSTO 1
Also any type of query for your old schema can be easily converted to new schema.
However if you need store additional information about every particular report I suggest having two tables:
Submissions
submission_id report_id ct_number ct_value
primary key
auto-increment
------------------------------------------------
1 1 CT1 TSTO
2 1 CT2 DOME
3 1 CT3 TSTO
4 1 CT4 ASBA
5 2 CT1 DOME
6 2 CT2 TSTO
with report_id pointing to a record in another table with as many columns as you need for additional data:
Reports
report_id officer date some_other_data
primary key
auto-increment
--------------------------------------------------------------------
1 1 2011-04-29 11:28:15 Everything went ok
2 2 2011-04-29 14:01:00 There were troubles
Example:
How many TSTO's are there for different officers:
SELECT r.officer, s.ct_value, count( officer ) as ct_count
FROM submissions s JOIN reports r ON s.report_id = r.report_id
WHERE s.ct_value='TSTO'
GROUP BY r.officer