如何检索与SQL中的查询顺序不同的数据?

时间:2010-11-30 20:42:03

标签: sql where-clause data-retrieval

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

这就是我想要的。例如:

我的表名为studentScore,有两列:

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

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

8 个答案:

答案 0 :(得分: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%'

但我真的不会这样做。

答案 1 :(得分:0)

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

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

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

这是最简单的方法 但我建议你改变你现在提到的整个表结构 有几次,因为你没有可能利用索引或密钥 这会耗尽几十个访客的电脑耗尽电脑

答案 2 :(得分:0)

我认为它是可以解决的,但如果每个学生的分数存储为单独的行,例如在scores表中,则会更简单。否则,代码必须将条目置于每个可能的顺序中。或者分数条目必须以某种方式处于标准顺序。

答案 3 :(得分: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搜索所有内容。

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

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

改进架构将为您节省大量的麻烦(源于更新异常)。

答案 6 :(得分:0)

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

然而,问题是:

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

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

答案 7 :(得分: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