Table structure for reporting SQL Performance - sql

I am not sure if this is the best structure for what I am trying to do.
I have 2 tables.
First table called Team which contains 3 columns, Team ID, Team Name and Kit Colour. This table contains data about the team only.
Second table called player name contains 3 columns, Player ID, Player name and Team ID. More columns will be added soon. Player table is about the player only. Team ID is the foreign key which links both tables together. A team can only have 15 players max so there can be 15 player entries for each team.
There can be thousands of teams with a maximum of 15 players each.
I have a horizontal Report that I need to fill that looks like this:
Team Name | Player 1 Name | Player 2 Name | Player 3 Name....| Player Name 15
My question is, I this best table structure set up for the report? How would I get data of a certain team with performance in mind? For example I want information for Team A, and all its players. There can be 15 players. If I can display the information in one select statement from left to right, I can easily fill in the report but this can t be done without using multiple selects which can be negative towards performance.
The other table structure that was suggested was having join both tables together instead of 2 table. A column for each player and their properties would have a column as well but this does not look correct as table would be massive and more player properties can be added.
I am using SQL 2008

You need to have two separate tables one for team and one for players, since team attributes can be common for multiple players it's better to have them separated rather having all together and duplicating, in your case TeamID serves as the link between both team and player table. so two table with a one to many relation ship is your ideal choice in my opinion.
To retrieve the information of a specific team you can use a simple join and a select statement
SELECT *
FROM TEAM T
INNER JOIN Player P
on T.TeamID=P.TeamID
WHERE T.TeamID=''

Related

Excluding data pairs from a query based on a table?

I have a massive and messy database of facilities where there are many duplicates. Addresses have been entered in such a haphazard way that I will be making many queries to identify possible duplicates. My objective is for each query to identify the possible duplicates, and then a person actually goes through the list and marks each pairing as either "not a duplicate" or "possible duplicate."
When someone marks a facility pair as not a duplicate, I want to record that data pair in a table so when that when one of the queries would otherwise return that pairing, it is instead excluded. I am at a loss for how to do this. I'm currently using MS Access for SQL queries, and have rudimentary visual basic knowledge.
Sample of how it should work
Query 1 is run to find duplicates based on city and company name. It brings back that facilities 1 and 2, 3 and 4, 5 and 6 are possible duplicates. The first two pairings are duplicates I need to go fix, but that 5 and 6 are indeed separate facilities. I click to record that facilities 5 and 6 are not duplicates, which records the data in a table. When query 1 is run again it does not return that 5 and 6 are possible duplicates.
For reference, the address duplicates look something like this, which is why there need to be multiple queries
Frank's Garage, 123 2nd St
Frank's Garage LLC, LLC, 123 Second st
Frank's Garage and muffler, 123 2nd Street
Frank's, 12 2nd st
The only way I know to fix this is to create a master table of company names and associate this table PK with records in original table. It will be a difficult and tedious process to review records and eliminate duplicates from master and associate remaining PK of a duplicate group to the original records (as you have discovered).
Create a master table of DISTINCT company and address data from original table. Include autonumber field to generate key. Join tables on company/address fields and UPDATE a field in original table with this key. Have another field in original table to receive a replacement foreign key.
Have a number field (ReplacementPK) in master table. Sort and review records and enter the key you want to retain for company/address duplicates group. Build a query joining tables on original key fields, update NewFK field in original table with selected ReplacementPK from master.
When all looks good:
Delete company and address and original FK fields from original table.
Delete records from master where PK does not match ReplacementPK.

SQL Server Mgmt Studio-random assign data to new column from another table

I am having trouble with a class assignment and I've gone thru various iterations.
The assignment is: "Randomly assign a serial number of a bat to each player by populating the new column you created in the AFFILIATION table. Make sure you abide by the team number that is included in the BATS table (i.e., do not associate a bat’s serial number with a player whose team does not have that bat)."
The table info is: Affiliation table has playernum as a PK, Teamnum as a PK, years, battingavg and playerbat. Playerbat is the new column that was created referenced in the assignment and has no data.
Bats table has serialnum as a PK, manuf and teamnum
Team table has teamnum as a PK, teamname, city, manager
Player table only has playernum as PK, playername, and age so you can’t relate it back to any other tables
The "randomly assign" portion of the assignemnt is related to the fact that a team has more than one bat serialnum in the bats table. Also players can play for more than one team.
This is what my last iteration looked like.
UPDATE affiliation SET playerbat = (SELECT serialnum FROM bats WHERE bats.teamnum = affiliation.teamnum
I’m using SQL server management studio btw, and it returns more than 1 value which is not permitted… I'm just seriously lost at this point. This is the last assignment in a SQL intro class.

MS-Access 2007: Query for names that have two or more different values in another field

Hello & thank you in advance.
I have an access db that has the following information about mammals we captured. Each capture has a unique ID, which is the capture table's primary key: "capture_id". The mammals (depending on species) have ear tags that we use to track them from year to year and day to day. These are in a field called "id_code". I have the sex of the mammal as it was recorded at capture time in another field called sex.
I want a query that will return all instances of an id_code IF the sex changes even once for that id.
Example: Animal E555 was caught 4 times, 3 times someone recorded this animal as a F and once as a M.
I've managed to get it to display this info by stacking about 5 queries on top of each other (Query for recaptured animals -> Query for all records of animals from 1st query -> Query for unique combo of id & sex (via just using those two columns & requiring "Unique Values") -> Query that pulls only duplicate id values from that last one and pulls back up all capture records of those ids). HOwever, this is clearly not the right way to do this, it is then not updateable (which I need since this is for data quality control) and for some reason it also returns duplicates of each of those records...
I realize that this could be solved two other ways:
Using R to pull up these records (I want none of this data to have to leave the database though, because we're working on getting it into one place after 35 years of collecting! And my boss can't use R and I'm seasonal, so I want him to just have to open a query)
Creating a table that tracks all animal id's as an animal index. However, this would make entering the data more difficult and also require someone to go back through 20,000 records and create a brand new animal id for every one because you can't give ear tags to voles & things so they don't get a unique identifier in the field.
Help!
It is quite simple to do with a single query. As a bonus, the query will be updatable, not duplicated, and simple to use:
SELECT mammals.ID, mammals.Sex, mammals.id_code, mammals.date_recorded
FROM mammals
WHERE mammals.id_code In
(select id_code from
(select distinct id_code, sex from [mammals]) a
group by id_code
having count(*)>1
);
The reason why you see a sub-query inside a sub-query is because Access does not support COUNT(DISTINCT). With any other "normal" database you would write:
SELECT mammals.ID, mammals.Sex, mammals.id_code, mammals.date_recorded
FROM mammals
WHERE mammals.id_code In
(select id_code
from [mammals]
group by id_code
having count(DISTINCT Sex)>1
);

Query to retrieve data using two foreign keys

I'm working on a football statistics database, and in the table to store results of matches, I have two references to the primary key of a team table: one home, one away.
My intention is to create a query which returns the name of both of the teams, along with other details, but I can't think of a way to achieve this WITH the team names (my attempts so far can only produce one team name, with the other an ID number). I'll give the relation structure if this wasn't clear:
(PKs in bold, FKs asterisk)
team(team_id, team_name, venue)
match(match_id, home_team*, away_team*, home_score, away_score, date,)
My desired output would be a table with these columns:
home_team_name, home_team_score, away_team_score, away_team_name, date, venue
Is this possible with my tables, or should I change the way I store results?
When joining the team table to the match table in a query, you'll need to join the match table to the team table twice. You need to use an different alias for the teams each time.

How to merge two identical database data to one?

Two customers are going to merge. They are both using my application, with their own database. About a few weeks they are merging (they become one organisation). So they want to have all the data in 1 database.
So the two database structures are identical. The problem is with the data. For example, I have Table Locations and persons (these are just two tables of 50):
Database 1:
Locations:
Id Name Adress etc....
1 Location 1
2 Location 2
Persons:
Id LocationId Name etc...
1 1 Alex
2 1 Peter
3 2 Lisa
Database 2:
Locations:
Id Name Adress etc....
1 Location A
2 Location B
Persons:
Id LocationId Name etc...
1 1 Mark
2 2 Ashley
3 1 Ben
We see that person is related to location (column locationId). Note that I have more tables that is referring to the location table and persons table.
The databases contains their own locations and persons, but the Id's can be the same. In case, when I want to import everything to DB2 then the locations of DB1 should be inserted to DB2 with the ids 3 and 4. The the persons from DB1 should have new Id 4,5,6 and the locations in the person table also has to be changed to the ids 4,5,6.
My solution for this problem is to write a query which handle everything, but I don't know where to begin.
What is the best way (in a query) to renumber the Id fields also having a cascade to the childs? The databases does not containing referential integrity and foreign keys (foreign keys are NOT defined in the database). Creating FKeys and Cascading is not an option.
I'm using sql server 2005.
You say that both customers are using your application, so I assume that it's some kind of "shrink-wrap" software that is used by more customers than just these two, correct?
If yes, adding special columns to the tables or anything like this probably will cause pain in the future, because you either would have to maintain a special version for these two customers that can deal with the additional columns. Or you would have to introduce these columns to your main codebase, which means that all your other customers would get them as well.
I can think of an easier way to do this without changing any of your tables or adding any columns.
In order for this to work, you need to find out the largest ID that exists in both databases together (no matter in which table or in which database it is).
This may require some copy & paste to get a lot of queries that look like this:
select max(id) as maxlocationid from locations
select max(id) as maxpersonid from persons
-- and so on... (one query for each table)
When you find the largest ID after running the query in both databases, take a number that's larger than that ID, and add it to all IDs in all tables in the second database.
It's very important that the number needs to be larger than the largest ID that already exists in both databases!
It's a bit difficult to explain, so here's an example:
Let's say that the largest ID in any table in both databases is 8000.
Then you run some SQL that adds 10000 to every ID in every table in the second database:
update Locations set Id = Id + 10000
update Persons set Id = Id + 10000, LocationId = LocationId + 10000
-- and so on, for each table
The queries are relatively simple, but this is the most work because you have to build a query like this manually for each table in the database, with the correct names of all the ID columns.
After running the query on the second database, the example data from your question will look like this:
Database 1: (exactly like before)
Locations:
Id Name Adress etc....
1 Location 1
2 Location 2
Persons:
Id LocationId Name etc...
1 1 Alex
2 1 Peter
3 2 Lisa
Database 2:
Locations:
Id Name Adress etc....
10001 Location A
10002 Location B
Persons:
Id LocationId Name etc...
10001 10001 Mark
10002 10002 Ashley
10003 10001 Ben
And that's it! Now you can import the data from one database into the other, without getting any primary key violations at all.
If this were my problem, I would probably add some columns to the tables in the database I was going to keep. These would be used to store the pk values from the other db. Then I would insert records from the other tables. For the ones with foreign keys, I would use a known value. Then I would update as required and drop the columns I added.