I've been making an award system in ms access but trying to use the if statement for 2 distinct parameters, i.e. in one class top 3 students get a different amount from what the top 3 students of another class might get. All the data of all classes is in one table.
See:
Student ID Class ID Average Rank Awards
1111 Form4 77.79166667 2
1189 Form4 105 1
1222 Form4 73.41666667 3
1234 Form4 69.95833333 4
1235 Form 3 77.16666667 3
1236 Form 3 72.875 4
1258 Form 3 82.54166667 1
1333 Form 3 77.25 2
1367 Form 2 56.54545455 4
1445 Form 2 75.66666667 2
1447 Form 2 75.72727273 1
1465 Form 2 74.18181818 3
1523 Form 1 76.18181818 3
1542 Form 1 75.51515152 4
1552 Form 1 79.03030303 2
1555 Form 1 79.63636364 1
at the awards column when creating a query the build formula I use i.e. IIf([Rank]=1,1100) gives all student IDs ranked 1 an award of 1100 but I want only form 1 student IDs to get 1100 and the others ranked 1st with different award values please assist.
I think you want something like:
IIF([ClassID] <> "Form 1", IIf([Rank]=1,500), IIf([Rank]=1,1100))
Obviously, you will have to edit the award amount since you didn't specify what you were giving, but the logic should hold true.
If this gets a bit more complicated, you can write a function in VBA (in any code module in the 'modules' section), and use it in the query:
ExpressionName: evaluateAward(ClassID, Rank)
In the function, you can then use nested select case statements. This may be much better for readability.
Related
I'm trying to join a few tables in MySQL. Our setup is a little unique so I try to explain as good as I can.
I have a table 'INVENTORY' that represents the current items on stock.
These items are stored in a table 'COMPONENT'
Components are being used in installations.
Every user can have multiple installations and the same component can be used in multiple installation as well.
To uniquely map a component to an installation, it can be assigned to a PRODUCT. a product as has a 1-1 relationship with an installation. A component is not directly related to an installation
To finally assign a product to a specific installation a mapping table COMPOMENT_PRODUCT is used.
Example:
A component is like a part, lets say a screw. This screw is used in a computer. The very same screw can be used on multiple computers. But each computer can only be used on one specific installation.
TABLE COMPOMENT_PRODUCT
COMPOMENT_ID PRODUCT_ID
1 1
1 2
2 1
2 2
So we have the components C1 and C2 relevant for two installations.
TABLE INVENTORY
COMPOMENT_ID INSTALLATION_ID ON_STOCK
1 1 5
1 2 2
What I want to achieve
Now, I want to retrieve the inventory state for all components. But, not every component has an inventory record. In these cases, the ON_STOCK value from the inventory shall be NULL
That means, for this example I'd expect the following results
COMPOMENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 2
2 1 NULL
2 2 NULL
But executing this query:
SELECT DISTINCT
COMPONENT_PRODUCT.COMPONENT_ID,
COMPONENT_PRODUCT.PRODUCT_ID,
INVENTORY.ON_STOCK
FROM INVENTORY
RIGHT JOIN COMPONENT_PRODUCT ON COMPONENT_PRODUCT.COMPONENT_ID =
INVENTORY.COMPONENT_ID
returns the following resultset:
COMPONENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 5
1 1 2
1 2 2
2 1 (null)
2 2 (null)
Now, my next thought was, "of course, this is how joins behave, okay I need to group the results". But the way SQL works, the aggregation is not entirely predictable. SO when I
GROUP BY COMPONENT_PRODUCT.COMPONENT_ID,COMPONENT_PRODUCT.PRODUCT_ID
I get this result:
COMPONENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 5
2 1 (null)
2 2 (null)
I have prepared a Fiddle here: http://sqlfiddle.com/#!9/71ca87
What am I forgetting here? Thanks in advance for any pointers.
Try this query -
SELECT DISTINCT
COMPONENT_PRODUCT.COMPONENT_ID,
COMPONENT_PRODUCT.PRODUCT_ID,
INVENTORY.ON_STOCK
FROM INVENTORY
RIGHT JOIN COMPONENT_PRODUCT ON COMPONENT_PRODUCT.COMPONENT_ID =
INVENTORY.COMPONENT_ID
AND COMPONENT_PRODUCT.PRODUCT_ID = INVENTORY.INSTALLATION_ID
I have a this Table in MS Access:
Table1
ID EMP ROLE ASSESS
1 JOE Weld 4
2 TOM Weld 4
3 JIM Ship 4
4 PAT Ship 3
5 JAY Weld 4
6 TIM Ship 4
"ROLE" is short text and "ASSESS" is a number field. "ASSESS" is assessing employees' roles on a scale of 1-4. I want to collect and total assessments that are "4" for each role.
Returning something like:
ROLE TOTAL
Weld 3
Ship 2
I however have around 100 different roles that I am needing to do this with. Is there a way with SQL or a combination of query and macro to make this work? I am at a loss.
Thank you.
You could use a where clause to filter just the the assesses that are 4 and a group by clause to aggregate them:
SELECT role, COUNT(*)
FROM table
WHERE assess = 4
GROUP BY role
I'm building a e-Commerce platform (PHP + MySQL) and I want to add a attribute (feature) to products, the ability to specify (enable/disable) the selling status for specific city.
Here are simplified tables:
cities
id name
==========
1 Roma
2 Berlin
3 Paris
4 London
products
id name cities
==================
1 TV 1,2,4
2 Phone 1,3,4
3 Book 1,2,3,4
4 Guitar 3
In this simple example is easy to query (using FIND_IN_SET or LIKE) to check the availability of product for specific city.
This is OK for 4 city in this example or even 100 cities but will be practical for a large number of cities and for very large number of products?
For better "performance" or better database design should I add another table to table to JOIN in query (productid, cityid, status) ?
availability
id productid cityid status
=============================
1 1 1 1
2 1 2 1
3 1 4 1
4 2 1 1
5 2 3 1
6 2 4 1
7 3 1 1
8 3 2 1
9 3 3 1
10 3 4 1
11 4 3 1
For better "performance" or better database design should I add
another table
YES definitely you should create another table to hold that information likewise you posted rather storing in , separated list which is against Normalization concept. Also, there is no way you can gain better performance when you try to JOIN and find out the details pf products available in which cities.
At any point in time if you want to get back a comma separated list like 1,2,4 of values then you can do a GROUP BY productid and use GROUP_CONCAT(cityid) to get the same.
I have a SharePoint list with 5 options (questions). Each option has a dropdown with values 1-6. The user (employee of a company) needs to select an option, then select a value from the dropdown and hit Submit. The selected value is unique. In other words, if the user selects the value 1 for the first option, that value cannot be chosen again. Here's an example form -
Category Rank
------------------------------
1. Work/Life Balance 4
2. Compensation 2
3. Commute 3
4. Work 1
5. Development 5
After filling the form, the data looks likes this on the Sharepoint list -
Employee Manager Work/Life Compensation Commute Work Development
--------------------------------------------------------------------------------
1. Employee 1 Manager 1 2 4 3 1 5
2. Employee 2 Manager 3 1 3 4 5 2
3. Employee 3 Manager 1 5 4 2 3 1
4. Employee 4 Manager 2 4 1 5 2 3
I'm able to get the Y-axis (for Rank) on the report just fine. The X-axis needs to display each category grouped by each Manager. Here's a sample of how I want it to look like -
Each colored bar on the X-axis is a Manager. This is my first time with SSRS (2012) and I'm just not sure how to accomplish this. If this is not possible, will moving the data to a SQL table in a different layout help? Any help is greatly appreciated.
You could aggregate each employee's response into an average in your dataset (I'm assuming you know how to do this):
Averages (just pretend)
Manager Work/Life Compensation Commute Work Development
--------------------------------------------------------------------------------
1. Manager1 2 4 3 1 5
2. Manager3 1 3 4 5 2
3. Manager2 4 1 5 2 3
Then you can use the categories as you have, with the manager as the series field. Pretty sure that should achieve what you're looking for.
Supoose I have the following:
tbl_options
===========
id name
1 experience
2 languages
3 hourly_rate
tbl_option_attributes
=====================
id option_id name value
1 1 beginner 1
2 1 advanced 2
3 2 english 1
4 2 french 2
5 2 spanish 3
6 3 £10 p/h 10
7 3 £20 p/h 20
tbl_user_options
================
user_id option_id value
1 1 2
1 2 1
1 2 2
1 2 3
1 3 20
In the above example tbl_user_options stores option data for the user. We can store multiple entries for some options.
Now I wish to extend this, i.e. for "languages" I want the user to be able to specify their proficiency in a language (basic/intermediate/advanced). There will also be other fields that will have extended attributes.
So my question is, can these extended attributes be stored in the same table (tbl_user_options) or do I need to create more tables? Obviously if I put in a field "language_proficiency" it won't apply to the other fields. But this way I only have one user options table to manage. What do you think?
EDIT: This is what I propose
tbl_user_options
================
user_id option_id value lang_prof
1 1 2 null
1 2 1 2
1 2 2 3
1 2 3 3
1 3 20 null
My gut instinct would be to split the User/Language/Proficiency relationship out into its own tables. Even if you kept it in the same table with your other options, you'd need to write special code to handle the language case, so you might as well use a new table structure.
Unless your data model is in constant flux, I would rather have tbl_languages and tabl_user_languages tables to store those types of data:
tbl_languages
================
lang_id name
1 English
2 French
3 Spanish
tbl_user_languages
================
user_id lang_id proficiency hourly_rate
1 1 1 20
1 2 2 10
2 2 1 15
2 2 3 20
3 3 2 10
Designing a system that is "too generic" is a Turing tarpit trap for a relational SQL database. A document-based database is better suited to arbitrary key-value stores.
Excepting certain optimisations, your database model should match your domain model as closely as possible to minimise the object-relational impedance mismatch.
This design lets you display a sensible table of user language proficiencies and hourly rates with only two inner joins:
SELECT
ul.user_id,
u.name,
l.name,
ul.proficiency,
ul.hourly_rate
FROM tbl_user_languages ul
INNER JOIN tbl_languages l
ON l.lang_id = ul.lang_id
INNER JOIN tbl_users u
ON u.user_id = ul.user_id
ORDER BY
l.name, u.hour
Optionally you can split out a list of language proficiencies into a tbl_profiencies table, where 1 == Beginner, 2 == Advanced, 3 == Expert and join it onto tbl_user_languages.
i'm thinking it's a mistake to put "languages" as an option. while reading your text it seems to me that english is an option, and it might have an attribute from option_attributes.