Grouping age in database - sql

I have designed my database and all is well. Within the database I have an Age column.
One of the requirements is that Age must be grouped into categories 1-12, 13-17, 18-25, 26-35 etc for easy selection.
I am a bit stumped with how to do this? I have not been asked to actually implement the database, only design the ERD.
I'm not sure if this is enough info for someone to answer, so if you need anything more please just ask.
EDIT:
I have been told that I do not have to allow for changing ages over time.

I think a better solution than adding a new column to the data is simply to define a view on the original table:
create view vw_customer as (
select c.*,
(case when Age between 1 and 12 then '1-12'
when Age between 13 and 17 then '13-17'
when Age between 18 and 25 then '18-25'
when Age between 26-35 then '26-35'
end) as AgeGroup
from c;
Another alternative, if your database supports it, is computed columns. There seems little reason why such derived data should actually be stored with the data, when SQL provides other alternatives.

I would suggest adding another column that is called something along the lines of AgeBracket to minimise information loss.
You could then do one of two things
1) have an update statement (or do it on the insert)...
UPDATE customer
SET AgeBracket = case when Age<=12 then '1-12' when Age<=17 then '13-17' .... end
WHERE AgeBracket IS NULL
-- alternative approach
INSERT INTO Customer(Name,Age,AgeBracket)
VALUES(#Name, #Age, case when #Age<=12 then '1-12' ....end)`
or 2) you could create a lookup table which has the structure MaxAge , AgeBracketLabel and join it where Age<=MaxAge and refer to the label - this is useful if/when it becomes more complex or more information about the brackets is required

Related

SQL query using fn_Split to find multiple values in column

This is a followup to my earlier question which got me part of the way to the goal.
Here is what I'm starting with:
SELECT * FROM MyTable WHERE County IN (SELECT value From dbo.fn_Split(#counties, ','))
Here's the scenario: In my table I've got a column named County. Each record can have multiple counties in the County column delimited with commas (I know this is bad form, I didn't do it). For example: county1, county22, county41. Some records may have only one county (say county13) others might have all the counties. So: county1, count2, county3... through county45 (yes, it's terrible, I know).
In the app I'm trying to build users can select multiple counties or even all counties in the same format as above (county1, county2, county3...). Thanks to Martin's help in the previous question I can get it to return records that have each of the counties individually but not the records that might contain all of the counties.
For example: The user selects county4, county26. I need to have the records returned that have just county4 and county26 as well as any that might contain both of them as part of a larger set (like all 45 of them).
Hope this is clear and I didn't make it more convoluted than necessary. Any assistance is very, very, very much appreciated!
To illustrate:
County
Record1 county1, county14, county26
Record2 county14
Record3 county1, county2, ... through county45
User Submission: county1, county26
Returns: Record1 and Record3
Not sure if I understood the question, but here is how I interpret it:
You need to return rows from your table for one or more selected items.
Also, you want to be able to select ALL items at once without passing the whole list.
I'd do that using Stored Procedure with 2 parameters:
#Selection SMALLINT
#TVP_County CountyTableType (It is Table Valued Variable. See: https://msdn.microsoft.com/en-us/library/bb510489.aspx)
If #Selection = 1 then you join #TVP_County with your table to get results.
If #Selection = 0 you return ALL records from your table w/o join and do not use #TVP_County at all.
If #Selection = -1 then you exclude #TVP_County items from your table. In that case you will be able to do a reverse marks. User will be able to select just few counties, which he/she does not want to see.
Of cause, within a stored procedure you have to implement the logic to run three different queries depending on the first parameter.

How to retrieve a column value using a variable

I have a single SQL table with columns Mary, Joe, Pat and Mick
I have rows of values for each persons weekly expenses
I want a single sproc to query a persons weekly expense value
i.e. a sproc that takes two variables #PersonsName and #WeekNumber and returns a single value
It wont work for me. It will work if I specify the persons name in the query but not if I pass the persons name to the query.
I'm pulling my hair out - is this something to do with Dynamic SQL?
Not sure if you are really digging into performance, scalability etc. as your scenario seems like a small personal tool. But still... as juergen suggested, you better design the schema in a different way. your current design won't scale easily if you want to add one more person to your database.
Instead, you can have something like
a persons table(person name, person Id)
an expenses table (week number, person id, expense)
This scales well. and with indexing on person id your queries can be faster
Suggestions apart,
Can I pass variable to select statement as column name in SQL Server seems to provide answer for your question

How to append two columns into one column in SQL?

I have two columns in my Table called as Workers - Technicians. In Workers I have name of workers, and in Technicians I have name of technicians who is working in company. Here is how it looks:
Workers Technicians
Andy Kevin
Conan Jason
Jay Ray
Donald Daryl
Martin .
Mark .(rows goes on)
.
.(rows goes on)
What I want to do is to append these rows and having a column called Employees. Here what i want:
Employees
Andy
Conan
Jay
Donald
Martin
Mark
Kevin
Jason
Ray
Daryl
.
.
I don't want to create another table, I just want to add a new column. How would i do this?
An union statement should do the job here. Something like this:
select Name from Workers-Technitians where Worker not null
UNION
select Name from Workers-Technitians where Technitian not null
Keep in mind that both queries must have an equal column count when using an union
Assuming your table is named "staff", you could do something like this.
select distinct employees from (
select workers as employees from staff s1
union select technicians as employees from staff s2
) as emps
Perhaps you need to take another look at your design, though. Adding a third column won't work out for you because the first two columns represent two rows. In fact, there already appears to be a forced relationship between the workers and technicians-- they seem to be bundled together in the same record for no particular reason.
Consider starting fresh with an Employee table, with one employee per row, and abandon the existing table. You can maintain employee attributes in that table if the requirements are simple, or join a separate table of attributes for more complex cases. In either case, normalizing your data will make your life easier and use of a union to join columns will be unnecessary.
I also don't understand fully what you want to do (mainly because of this: if, say, a row has "Andy" in Workers and "Kevin" in Technicians, what will you put in Employees? Andy or Kevin?), but to add a new column to the table and then fill it with data you need to:
Add it (assuming your table is named Table and 100 chars are enough for the new column):
alter table [Table] add [Employees] nvarchar(100) null
Fill it:
update [Table] set [Employees] = [Workers]
-- or:
update [Table] set [Employees] = [Technicians]
I believe what you really want is a new table, Employees, and to change the Workers and Technicians into relationships drawn from it. For that, see the link Simon gave you about database normalization.
I don't entirely understand your question but you don't want to add an additional column, this introduces (more) data redundancy and will make any future updates or querying more difficult. Use one of the SELECT query solutions given and seriously consider re-factoring your two existing separate columns into a single column. I suggest you take a look at database normalisation if you're not already familiar with the concept.

Sorting across a row in Microsoft Access

What I need is to re-arrange the columns in a table by the order specified in a row.
So if I had:
one four two three
1 4 2 3
How could I get:
one two three four
1 2 3 4
I have considered creating a new table and looking at each of the elements and its neighbor individually and copying the lowest element to the new table and repeating throughout the table until all the elements have moved.
Would this method work?
If so is it necessary I do it in VBA (I don't have much experience with this)?
Or is there a method in SQL?
Thanks for any help.
SQL is based on the relational model of data. One of the principles of the relational model is that the order of columns is meaningless.
But if you absolutely have to do this in Access, use a query, a form, or a report. You can put the columns in any order you like in any of these three, and it won't affect the base table at all.
If the order of items is important, they are typically stored in rows, not columns, for example, a table with the following fields : StudentID, ExamID, ExamDate can be sorted by StudentID and ExamDate to give a useful order, regardless of the order of entry. Furthermore, a crosstab query will allow the presentation of data in columns.
If the order of columns has become important, it is nearly always an indication of an error in the table design. You may wish to read Fundamentals of Relational Database Design, Paul Litwin, 2003

How to get specific row, knowing the primary key value?

This is probably very easy question for you sql gurus, but I never used sql before.
If the table "Person" has 3 rows : Name (primary key), Age and City, I know I can get all rows like this :
SELECT * FROM Person;
But if the table looks like this :
Name Age City
-------------------
A 2 NY
B 4 BE
C 6 PA
What sql command do I have to use to get (for example) the 2nd row? I know the Name is B.
SELECT * FROM Person WHERE Name = 'B';
This solves this particular problem, but you can visit w3schools sql tutorial for the starting.
SELECT * FROM Person
WHERE Name = 'B';
Try SELECT * FROM Person WHERE Name='B' more about select syntax you can find here http://dev.mysql.com/doc/refman/5.0/en/select.html
You should avoid using primary keys that are related to any data in the entity. There is almost never a good pick. Primary keys should not change... Names can change (Both for cities and Persons) Also a SSN might "look" like a good candidate, but even they rotate over time, and you might happen to employ an illigal alien with a faked SSN Number ;)
So please allways use an integer that just counts up, or a guid.
Besides that, the answer has been posted several times already...
Rather than ask a question about each aspect of sql on here (you'll probably have quite a few), do a bit of reading first:
http://w3schools.com/sql