0

我正在尝试从 SQL 中的表中检索记录。

这就是我想要的。例如:

我有一个包含两列的表名 studentScore:

studentName -----  Scores
John Smith  ----- 75,83, 96

我想这样做:当我在搜索框中输入分数时,我希望它显示学生的姓名。例如:我可以输入“83, 96, 75”(分数可以是任意顺序),这应该会显示学生姓名“John Smith”。但是我想知道如果我们在框中键入的内容与列中的原始数据的顺序不同,我们如何在 WHERE 子句中指定以便它选择正确的记录?

4

8 回答 8

2

您的问题是您的数据未正确规范化。您正在将 1 对 n 关系放入单个表中。如果您要像这样重新组织表格:

Table Students

id  name
1   John Smith

Table Scores

studentId score
1         75
1         83
1         96

您可以执行如下查询:

select st.name from Students st, Score sc where st.id = sc.studentId and sc.score in ("83", "75", "96")

如果您想要进行其他查询,例如找出哪些学生的分数至少为 X,这也很有帮助,否则您现有的表格布局是不可能的。

如果您必须坚持现有的布局,我不建议这样做,但是您可以拆分用户输入,然后执行如下查询

select from studentScore where score like '%75%' or score like '%83%' or score like '%96%'

但我真的不会这样做。

于 2010-11-30T20:52:50.417 回答
0

我想这是可以解决的,但如果每个学生的分数存储为单独的行,例如在一个scores表中,它会更简单。否则,代码将不得不将条目置换到每个可能的订单中。或者分数条目必须以某种标准顺序排列。

于 2010-11-30T20:47:05.490 回答
0

这是一个数据库规范化应该对你有很大帮助的例子。

您可以像这样存储您的数据(编辑:如果您想保留订单,您可以添加一个订单列)

studentName        Scores    Order
John Smith         75        1
John Smith         83        2
John Smith         96        3
Foo bar            73        1
Foo bar            34        2
........

但是,如果您坚持使用当前模型,则下一个最佳选择是对 Scores 列进行排序,那么您只需从文本框中获取搜索字符串,对其进行正确排序和格式化,然后您就可以进行搜索了。

最后,如果分数未在表中排序,您可以创建所有可能的组合

75, 83, 96
75, 96, 83
83, 75, 96
83, 96, 75
96, 75, 83
96, 83, 75

并使用 搜索它们OR

于 2010-11-30T20:49:48.957 回答
0

如果您不想为分数创建新表,例如使用 StudentId、分数列,您可以在存储之前对数字进行排序。

这样,当有人键入查询时,您也可以对这些数字进行排序,并将其与存储的字符串进行比较。

如果您需要乐谱的原始位置,可以将它们存储在单独的字段中。

于 2010-11-30T20:50:09.723 回答
0

改进您的数据库架构......这甚至不满足第一个范式(http://en.wikipedia.org/wiki/Database_normalization#Normal_forms)。

改进模式将在未来为您省去很多麻烦(源于更新异常)。

于 2010-11-30T20:50:56.223 回答
0

任何 sql 表都不应该有多个属性值(在同一列中)。分数是否存储为字符串?如果是这样,您的查询将更加复杂,并且您正在浪费数据库的意义。

但是,对于您的问题:

SELECT col4, col3, col2 FROM students WHERE col1 = 57; 

这将按 (4,3,2) 的顺序返回第 4、3 和 2 列,即使它们按 1、2、3、4 的顺序保存。SQL 按照您要求的顺序返回您要求的内容.

于 2010-11-30T20:51:54.217 回答
0

您可以使用正则表达式或 Like 运算符

正则表达式解决方案可能看起来像

SIMILAR TO '%(SCORE1|SCORE2|SCORE3)%' 

这是最简单的方法,但我建议您更改整个表结构,正如现在多次提到的那样,因为您无法利用索引或键,这会在几十个访问者的情况下耗尽计算机

于 2010-11-30T20:46:39.177 回答
0

所以,是的,我同意其他所有人的观点,即这种设计是垃圾。如果您要正确规范化此表,您将能够非常轻松地获得所需的数据。

但是,这就是您可以使用当前结构的方式。将用户输入拆分为离散分数。然后,将每个值传递到过程中。

CREATE PROCEDURE FindStudentByScores
    (
     @score1 AS VARCHAR(3) = NULL
    ,@score2 AS VARCHAR(3) = NULL 
    ,@score3 AS VARCHAR(3) = NULL 
    )
AS 
    BEGIN
        SELECT  *
        FROM    [Students]
        WHERE   ( @score1 IS NULL
                  OR [Scores] LIKE '%' + @score1 + '%' )
                AND ( @score2 IS NULL
                      OR [Scores] LIKE '%' + @score2 + '%' )
                AND ( @score3 IS NULL
                      OR [Scores] LIKE '%' + @score3 + '%' )

    END 
于 2010-11-30T20:53:28.420 回答