【问题标题】:how to compare 2 tables and create a new table and update daily如何比较 2 个表并创建一个新表并每天更新
【发布时间】:2020-02-25 21:24:27
【问题描述】:
table1

----------------|------------------|-------------------|-------------------|
|      email          |     selection1   | selection2        |     selection3
|                                                           
|---------------------|------------------|-------------------|-------------------|
|  test@test.com      |        4       |           7                     9
|---------------------|------------------|-------------------|------------------|
|test2@test.com                2                     9                6
---------------------|------------------|--------------------|-------------------|      

table2
|---------------------|------------------|-------------------|-------------------|
|      race1|                 race2      |         race3     |       race4
|                                                           
|---------------------|------------------|-------------------|-------------------|
|  5                   |        7       |           9                    2
|---------------------|------------------|-------------------|------------------|

所以,我有两张桌子。 一种是根据用户输入选择 3 场比赛作为获胜者的数量。

第二张表是比赛获胜者的号码。

我想比较这两个表并创建第三个表。如果这个人的选择与获胜的比赛相匹配,那么他们将获得 50 分。所以第三个表格会显示“email”和“points”

这将持续 4 天,因此如果同一电子邮件匹配另一位比赛获胜者,他们将获得额外 50 分。

我试过 INNER JOIN,但是组合太多了。我是 PHP 和 SQL 的新手,所以我真的不知道该采取什么方法。

【问题讨论】:

  • 你应该规范化表格
  • 这个数据库结构一团糟。如果你需要 50 场比赛,你会改变第二张桌子的结构吗?以及用户选择如何与这些比赛相对应,例如:selection1 = 2 在table1,但在table2 你有race4 = 2,这是否意味着用户获胜?
  • 基本上最上面的表格是用户输入的,所以他们提供了他们的电子邮件地址,然后为 3 场比赛(只有 3 场)挑选他们的选择。表 2 是每场比赛的结果。所以如果比赛 1 =1,并且用户选择 1 =1。他们得到 50 分。如果比赛 2 符合他们的选择 2,他们将再次获得 50 分。希望这更有意义

标签: php mysql database join denormalization


【解决方案1】:

您可以从数据库中提取值,然后遍历每个用户并将他们提交的内容与第二个表中的结果进行比较。像this 这样的东西应该能够帮助您完成第一部分(将数据从 MySQL 中提取到数组中)。

然后假设在将他们从数据库中提取出来之后,您有一个包含所有用户及其提交的 $users 数组,然后是一个包含每场比赛的获胜者的 $results 数组(table2 的内容)。然后,您可以使用 for 循环或 foreach 遍历每个用户并将他们的每个选择与结果进行比较。像这样的东西,例如:

<?
//Loop through each of the users in the $users array
foreach($users as $user)
{
    if($user['selection1'] == $results['race1'])
    {
        //Add to their points or whatever you would like to do
    }

    if($user['selection2'] == $results['race2'])
    {
        //Add to their points or whatever you would like to do
    }

    if($user['selection3'] == $results['race3'])
    {
        //Add to their points or whatever you would like to do
    }
}

?>

尽管如此,您可能希望重新组织您的数据库结构。因为如果你想在未来改变事情,这不是很灵活。此外,您提供的示例在第一个表中有 3 场比赛,但在第二个表中有 4 场。

【讨论】:

    【解决方案2】:

    您的首要任务是创建一个子查询,以电子邮件、选择的形式传递您的table1。看起来像这样 (https://www.db-fiddle.com/f/mbXAqAo6Y4MPd3jH9vAY4Q/0)

                 SELECT email, selection1 AS selection FROM table1
                 UNION ALL
                 SELECT email, selection2 AS selection FROM table1
                 UNION ALL
                 SELECT email, selection3 AS selection FROM table1
    

    接下来,对您的 table2 执行相同操作。 (https://www.db-fiddle.com/f/mbXAqAo6Y4MPd3jH9vAY4Q/1)

                 SELECT race1 AS race from table2
                 UNION ALL
                 SELECT race2 AS race from table2
                 UNION ALL
                 SELECT race3 AS race from table2
                 UNION ALL
                 SELECT race4 AS race from table2;
    

    然后,您需要计算出有多少 race 值与每个 selection 值匹配。这需要一个聚合函数。您的查询大纲是

       SELECT email, COUNT(race) races_chosen
         FROM selections
         JOIN races ON selections.selection = races.race
        GROUP BY email
    

    在这里,通过 JOIN 操作,您正在创建一个结果集,该结果集显示每封电子邮件以及在比赛中也出现的选择。然后你在数他们。

    这里的实际查询需要使用您的子查询。它看起来像这样。 (https://www.db-fiddle.com/f/mbXAqAo6Y4MPd3jH9vAY4Q/2)

       SELECT email, COUNT(race) races_chosen
         FROM (
                 SELECT email, selection1 AS selection FROM table1
                 UNION ALL
                 SELECT email, selection2 AS selection FROM table1
                 UNION ALL
                 SELECT email, selection3 AS selection FROM table1
    
              ) selections
         JOIN (
                 SELECT race1 AS race from table2
                 UNION ALL
                 SELECT race2 AS race from table2
                 UNION ALL
                 SELECT race3 AS race from table2
                 UNION ALL
                 SELECT race4 AS race from table2
              ) AS races ON selections.selection = races.race
        GROUP BY email
    

    最后,您可以将您的 SELECT 行更改为此以获得您的积分。 (https://www.db-fiddle.com/f/mbXAqAo6Y4MPd3jH9vAY4Q/3)

       SELECT email, COUNT(race) races_chosen, COUNT(races)*50 points
    

    您需要考虑几件事。

    1. 不要创建另一个表来包含此结果数据。相反,请在需要时使用查询来生成它。这更容易,因为您不必弄清楚更新额外表格的内容发生了什么变化;您只需即时生成结果。 SQL 就是为这种操作而设计的。

    2. 我给您使用的子查询具有获取denormalized 表并将它们标准化的效果。如果不对它们进行非规范化,生成结果的查询会复杂得多。您的表是非规范化的,因为它们在每一行包含多个事实。

    这就是我的意思。您的 table2 使用一行来显示四个不同的种族。相反,你应该每场比赛有一排。然后使用 INSERT 向表中添加另一场比赛或使用 DELETE 删除一场比赛会容易得多。它也使查询更容易。

    您的table1 是非规范化的,因为这是一种强制执行您的规则的方式,即每个电子邮件地址最多可以选择三场比赛。这是一个可以容忍的软件设计决策。但是,如果你想让他们在未来添加第四场比赛,修复你的应用程序变得更加困难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多