Reputation: 1171
I have a table with columns
id, playername, sport1, sport2
However, my requirements say that a player can have n number of sports, so a multi-value column 'sports' is needed or else I would be going with sport3, sport4, and so on. How do I alter the table to combine sport1, sport2 and use that as a multi-value column for new rows going forward?
Upvotes: 0
Views: 136
Reputation: 34177
sqlite does not support multivalued fields. The only DBMS I am aware of that can do this is Microsoft Access but I wouldn't, in general, recommend switching from sqlite to Access, even if you are guaranteed to be running on Windows computers only.
This is a classic problem of database design. I recommend you switch from a single table to multiple tables so that each entity type is accurately portrayed in the database. For example, the name of a sport is not an attribute of a player, it is an attribute of a sport, so you probably need a Sport table. You clearly need a Player table. And since players can play multiple sports, and each sport might be played by multiple players, you have a many-to-many relationship. This can be modelled in a RDBMS using multiple tables with foreign keys.
Consider the following database structure (think of this as pseudo-code though it may work as is).
CREATE TABLE Player (
PlayerId int NOT NULL PRIMARY KEY,
Name string NOT NULL UNIQUE
)
CREATE TABLE Sport (
SportId int NOT NULL PRIMAEY KEY,
Name string NOT NULL UNIQUE
)
CREATE TABLE PlayerSport (
PlayerId int NOT NULL FOREIGN KEY REFERENCES Player (PlayerId),
SportId int NOT NULL FOREIGN KEY REFERENCES Sport (SportId),
PRIMARY KEY (
PlayerId,
SportId
)
)
This structure comes about via a process of database normalization.
You can now get a list of all sports for a player,
SELECT
Sport.Name
FROM Sport
INNER JOIN PlayerSport ON PlayerSport.SportId = Sport.SportId
AND PlayerSport.PlayerId = @PlayerId
ORDER BY
Sport.Name
Or all players for a sport,
SELECT
Player.Name
FROM Player
INNER JOIN PlayerSport ON PlayerSport.SportId = Player.PlayerId
AND PlayerSport.SportId = @SportId
ORDER BY
Player.Name
Or all players and sports,
SELECT
Player.Name AS Player,
Sport.Name AS Sport
FROM Player
INNER JOIN PlayerSport ON PlayerSport.SportId = Player.PlayerId
INNER JOIN Sport ON Sport.SportId = PlayerSport.SportId
ORDER BY
Player.Name,
Sport.Name
But note that the structure of this final query is not the same as your original table. To output a row per player and a column per sport is not possible in static SQL. You could construct a dynamic query but this is not easy, is error prone, and fallible to sql-injection security breaches.
Upvotes: 0
Reputation: 2127
The classic solution is to have a second table with columns for the playerId and the sport. Then, to see all the sports a player has, join the two.
Upvotes: 4