如何避免在同一个表上进行多个连接(它有 200 列来保存 ID。另一个表有 ID 到值的映射)

1 database-design sql-server

我有一个包含以下列的表格清单

ChkId, Q1_ID, Comment1, Checked1, Q2_ID, Comment2, Checked2, ... Q200_ID...

我有一个包含以下列的表格问题

Q_ID,提示

如何用匹配的 Questions.Prompt 替换 Checklist.Q#_ID 而不将它们加入最多 200 次?有没有优雅的解决方案?

Vér*_*ace 5

看看我在这里的回答以了解为什么从关系数据库的角度来看,您的原始设计是一个非常糟糕的主意。

基本上,您已将两个实体“压扁”为一个!您的情况与该问题非常相似!您需要对数据进行规范化 - 这将极大地帮助您制定查询并提高查询速度!

似乎这里有两个实体(恕我直言)一个清单实体和一个问题实体。

清单由 checklist_id (chk_id) 标识,问题由 checklist_idquestion_id唯一标识。也许“测验”可能是一个更好的名字?您可以进行历史测验、体育测验等。具有不同的 chk_id。

因此,为了解决根本问题,您应该创建一个问题表(请参阅此处的SQLFiddle ):

CREATE TABLE question
(
  chk_id INTEGER NOT NULL,
  q_id INTEGER NOT NULL,
  q_comment VARCHAR (255) NOT NULL,
  q_checked BIT NOT NULL,
  CONSTRAINT question_pk PRIMARY KEY (chk_id, q_id)
);
Run Code Online (Sandbox Code Playgroud)

VIEW如果你不能改变底层的表结构,你可以在s 中实现我的策略- 这会有点笨拙,但仍然比你当前的场景好!

示例清单表:

从您的清单表和示例数据中提取的前 3 个问题的示例:

CREATE TABLE checklist -- you have this already!
(
  chk_id INTEGER PRIMARY KEY,
  q1_id  INTEGER NOT NULL,
  q1_comment VARCHAR (255) NOT NULL, -- or whatever size suits.
  q1_checked BIT NOT NULL,

  q2_id INTEGER NOT NULL,
  q2_comment VARCHAR (255),
  q2_checked BIT NOT NULL,

  q3_id INTEGER NOT NULL,
  q3_comment VARCHAR (255),
  q3_checked BIT NOT NULL

  -- &c. 197 times.
);

INSERT INTO checklist
VALUES
(233, 1, 'Good question!', 1, 2, 'Crap', 0, 3, 'Better', 1),
(234, 1, 'An OK question', 0,  2, 'Bleuch...', 1,  3, 'Brilliant!!', 0);
Run Code Online (Sandbox Code Playgroud)

如果“评论”字段是问题本身——即“提示”,请替换您选择的文本——我的评论是对问题的看法......不太确定。容易修改!

然后,您需要INSERT像这样构造一系列 200秒:

INSERT INTO question
SELECT 
  chk_id, 
  q1_id, 
  q1_comment, 
  q1_checked 
FROM checklist;
Run Code Online (Sandbox Code Playgroud)

你必须这样做 200 次 (q2...q200)。显然,这将需要一些工作(手动输入或脚本),让您的数据从原来的实体,但它是值得的,从长远来看!

以下是三个问题条目(通过两个清单 - 历史或运动):

SELECT * FROM question;
Run Code Online (Sandbox Code Playgroud)

结果:

chk_id  q_id          q_comment     q_checked
   233     1     Good question!          true
   233     2               Crap         false
   233     3             Better          true
   234     1     An OK question         false
   234     2          Bleuch...          true
   234     3        Brilliant!!         false
Run Code Online (Sandbox Code Playgroud)

您的表格将更加高效且更易于操作!