在SQL中搜索多列以查找值与在一列中存储值

在SQL中搜索多列以查找值与在一列中存储值,sql,database-design,Sql,Database Design,我需要在SQL数据库中存储乐透号码。有8个独立的号码组成乐透号码 例:07-12-34-40-59-80-88-89 我首先想到用名为lotto1-lotto8的列将这些数据存储在一行中。这是有意义的,因为乐透号码总是从低到高显示,用户需要查看存储的乐透号码。编写select语句将是微不足道的 我还要看看有多少彩票号码是中奖的。要做到这一点,我需要在每一列中搜索每个中奖号码 例:如果中奖号码是01-02-03-04-05-06-07-08,我需要检查每一列,看我的乐透1列中是否有“07” 如果所

我需要在SQL数据库中存储乐透号码。有8个独立的号码组成乐透号码

例:07-12-34-40-59-80-88-89

我首先想到用名为lotto1-lotto8的列将这些数据存储在一行中。这是有意义的,因为乐透号码总是从低到高显示,用户需要查看存储的乐透号码。编写select语句将是微不足道的

我还要看看有多少彩票号码是中奖的。要做到这一点,我需要在每一列中搜索每个中奖号码

例:如果中奖号码是01-02-03-04-05-06-07-08,我需要检查每一列,看我的乐透1列中是否有“07”

如果所有彩票号码都存储在1列中,并且他们有一个LottoTicketID将8行数据与1张彩票关联起来,那么检查中奖者就更容易了。在检查获奖者时,我不需要说哪些具体数字/位置是比赛,只需要说有多少场比赛

从LOTTOTABLE中选择LottoTicketID、计数(LottoTicketID) 其中LottoNumber在(01,02,03,04,05,06,07,08) 洛托蒂克提德分组

以这种方式存储会导致问题,因为我需要写7个连接来显示数字

是否有人可以建议一种存储此数据的方法,以便我可以: 1.快速显示乐透号码/整数 2.检查赢家

以这种方式存储会导致问题,因为我需要写7个连接来显示数字

如果您需要在一行上显示所有数字,则只需执行7次联接即可。如果您在数据库之外处理这些数据(甚至使用存储过程),那么将它们收集成可读的格式是很简单的


如果您的数据库支持,您可能有另一种选择,即将所有数字放在一个数组类型的列中,或者使用某种多行分析函数。你可以只写一个视图来解决这个问题一次。

为什么你需要写7个连接来显示数字?你可以这样写:

SELECT LottoNumber FROM LOTTOTABLE
WHERE LottoTicketID=n
ORDER BY LottoNumber
id   |   first_name   |   last_name   |   date_given   |   lottery_number
--------------------------------------------------------------------------------
823  |   Zane         |   Bien        |   2012-01-01   |   34-80-07-89-12-40-59-88
2321 |   Jeff         |   Clark       |   2012-01-14   |   59-07-88-40-12-34-80-89
您可以使用您建议的查询来检查它们:

SELECT LottoTicketID, Count(LottoTicketID) 
FROM LOTTOTABLE 
WHERE LottoNumber in (01,02,03,04,05,06,07,08) 
GROUP BY LottoTicketID
您还可以通过以下方式将此列表限制为仅限获奖者:

HAVING Count(LottoTicketID) = 8

您还可以将乐透号码存储为TINYINT,以减小数据库大小。

如您所述,将号码存储在单个列中有很多优点。如果剩下的唯一问题是将它们显示在一起的复杂性,那么有很多方法可以干净、轻松地实现这一点,而且经常被忽略,因此这个问题经常被问到

在这里,对于几种SQL风格以及一些独立于平台的选项,它得到了很好的处理:

解决这个问题的方法可能是使用两个表来存储彩票信息:

  • 彩票:要存储每个彩票的信息:

    lottery_tickets
    ----------------------
    id [PK]
    first_name
    last_name
    date_given
    ...
    
  • 彩票号码:存储相应彩票号码:

    lottery_ticket_numbers
    ----------------------
    id        [PK](FK)
    number    [PK]
    position  
    
通过1:N标识关系将
id
字段上的两个字段连接起来,并使每张彩票在
彩票号码表中有8个对应行。
位置
字段将跟踪整个数字串中每个数字的位置(1-8)

这将使您能够通过将表格连接在一起并缩小范围以确定哪些彩票具有所有匹配号码,从而轻松计算出中奖彩票:

SELECT
    a.*,
    GROUP_CONCAT(b.number ORDER BY position SEPARATOR '-') AS lottery_number
FROM
    lottery_tickets a
INNER JOIN
    lottery_ticket_numbers b ON a.id = b.id
WHERE
    b.number IN (07,12,34,40,59,80,88,89)
GROUP BY 
    a.id
HAVING 
    COUNT(b.number) = 8
结果集如下所示:

SELECT LottoNumber FROM LOTTOTABLE
WHERE LottoTicketID=n
ORDER BY LottoNumber
id   |   first_name   |   last_name   |   date_given   |   lottery_number
--------------------------------------------------------------------------------
823  |   Zane         |   Bien        |   2012-01-01   |   34-80-07-89-12-40-59-88
2321 |   Jeff         |   Clark       |   2012-01-14   |   59-07-88-40-12-34-80-89
注:

  • 如果您使用的是MySQL,则
    GROUP_CONCAT()
    函数会将中奖彩票的号码以XX-XX-XX-XX-XX-XX-XX-XX-XX的格式与获得该彩票的人的原始顺序进行合并。如果您不使用MySQL,我不确定其他DBMS中是否存在类似的函数
现在,您可能还需要存储有关实际中奖彩票号码的数据。为此,您还将以几乎相同的方式使用两个表:一个用于彩票号码,另一个用于相应的号码:

SELECT
    a.*,
    GROUP_CONCAT(b.number ORDER BY position SEPARATOR '-') AS lottery_number
FROM
    lottery_tickets a
INNER JOIN
    lottery_ticket_numbers b ON a.id = b.id
WHERE
    b.number IN (07,12,34,40,59,80,88,89)
GROUP BY 
    a.id
HAVING 
    COUNT(b.number) = 8
  • 中奖号码

    winning_numbers
    ----------------------
    id [PK]
    date_pulled
    
    winning_numbers_numbers
    ----------------------
    id     [PK](FK)
    number [PK]
    
  • 获胜号码\u号码

    winning_numbers
    ----------------------
    id [PK]
    date_pulled
    
    winning_numbers_numbers
    ----------------------
    id     [PK](FK)
    number [PK]
    
要查询中奖彩票,请执行以下操作:

SELECT
    a.*,
    GROUP_CONCAT(b.number ORDER BY position SEPARATOR '-') AS lottery_number
FROM
    lottery_tickets a
INNER JOIN
    lottery_ticket_numbers b ON a.id = b.id
WHERE
    b.number IN
    (
        SELECT number
        FROM winning_numbers_numbers
        WHERE id = <id of a particular lottery number>
    )
GROUP BY 
    a.id
HAVING 
    COUNT(b.number) = 8
请注意,当您插入中奖号码时,您根本不必担心插入号码的顺序。由于它们总是以升序显示,因此
组中的
order BY
将为您解决这一问题


现在让我们来看看如果使用基于列的方法(将获胜号和票号存储为单个行,但每个数包含八列): 假设模式为:

中奖号码(id、日期、n1、n2、n3、n4、n5、n6、n7、n8)

车票号码(id、fname、lname、给定日期、n1、n2、n3、n4、n5、n6、n7、n8)

查找给定彩票号码的所有中奖彩票:

选择
a*
从…起
车票号码a
内连接
中奖号码
a、 n1英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n2英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n3英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n4英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n5英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n6英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n7英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
a、 n8英寸(b.n1、b.n2、b.n3、b.n4、b.n5、b.n6、b.n7、b.n8)和
b、 id=
如果你问我的话,
s中的
太多了

这种方法的优点是不需要特定于MySQL的代码