如何将2列合并为一列,并使用该合并列来保存多个值

时间:2013-05-30 15:18:23

标签: mysql sql sqlite

我有一个包含列的表

id, playername, sport1, sport2

但是,我的要求是说玩家可以拥有n个体育项目,因此需要一个多值列“体育”,否则我将使用sport3,sport4等等。如何更改表格以结合sport1,sport2并将其用作新行的多值列?

2 个答案:

答案 0 :(得分:4)

经典的解决方案是拥有第二个表,其中包含playerId和sport的列。然后,要查看玩家所拥有的所有体育项目,请加入两者。

答案 1 :(得分:0)

sqlite不支持多值字段。我所知道的唯一可以做到这一点的DBMS是Microsoft Access,但我一般不会建议从sqlite切换到Access,即使你保证只在Windows计算机上运行。

这是数据库设计的经典问题。我建议您从单个表切换到多个表,以便在数据库中准确描绘每个实体类型。例如,运动的名称不是运动员的属性,它是运动的属性,因此您可能需要运动表。你显然需要一个播放器表。由于玩家可以进行多项运动,并且每项运动可能由多个运动员进行,因此您有many-to-many relationship。这可以使用带有外键的多个表在RDBMS中建模。

考虑以下数据库结构(将其视为伪代码,尽管它可以按原样工作)。

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
    )
)

这种结构是通过database normalization的过程实现的。

您现在可以获得玩家所有运动的列表,

SELECT
    Sport.Name
FROM Sport
    INNER JOIN PlayerSport ON PlayerSport.SportId = Sport.SportId
        AND PlayerSport.PlayerId = @PlayerId
ORDER BY
    Sport.Name

或所有体育运动员,

SELECT
    Player.Name
FROM Player
    INNER JOIN PlayerSport ON PlayerSport.SportId = Player.PlayerId
        AND PlayerSport.SportId = @SportId
ORDER BY
    Player.Name

或所有球员和运动,

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

但请注意,此最终查询的结构与原始表的结构不同。在静态SQL中无法为每个玩家输出一行,每个运动输出一列。您可以构造一个动态查询,但这并不容易,容易出错,并且容易导致sql-injection安全漏洞。