0

我有两张表与琐事问答游戏的这一部分有关:scoresquiz. 我已经嵌套了许多 PHP 和 MySQL 循环,我希望有一种更优雅的方式(并且希望更少的数据库查询)来实现相同的结果。

任何建议都非常感谢。

下面是我的 MySQL 结构、PHP 代码和一些示例数据。

quiz包含系统中每个测验的信息,每个测验一条记录:

  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `category_uid` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `sample` binary(2) NOT NULL,
  `difficulty` varchar(65) NOT NULL,
  `date_created` datetime NOT NULL,
  `date_updated` datetime NOT NULL,
  PRIMARY KEY (`uid`)

一个唯一的 ID、一个categories表的映射(此处不相关)、一个名称、是否是示例测验、难度等级、首次创建的日期以及上次更新的日期。

表格scores包含用户参加测验时的结果,测验中每个问题有一条记录(因此,10 道问题的测验有 10 行):

  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `unique_uid` varchar(255) NOT NULL,
  `question_uid` int(11) NOT NULL,
  `quiz_uid` int(11) NOT NULL,
  `user_uid` int(11) NOT NULL,
  `answer` varchar(255) NOT NULL,
  `correct` binary(2) NOT NULL,
  `points` int(25) NOT NULL,
  `time` float(20,1) NOT NULL,
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`uid`)

记录的唯一 ID,正在进行的测验实例的唯一 ID,映射到questions表(此处不相关),映射到quiz表,映射到users表(此处不相关),给出的答案,是否正确与否、得分、响应时间(以秒为单位)以及记录的时间戳。

由于玩家可以重新玩测验,因此每个都scores.unique_uid指向一次玩测验。这意味着玩家可能会玩quiz.uid=1 五次不同的游戏,这意味着在表格中score.unique_uid记录的总共(5 次 X 10 个问题 =)50 行中有五次不同的游戏。scores

我要做的是检索所有不同的scores.unique_uid记录(玩家得分的每个测验的列表),然后查看每组 10 条记录(一个测验,10 个问题)的一些表格结果。

我现在的做法是:

  1. quiz.uid循环查询返回玩家得分的每个唯一值
  2. 循环通过另一个查询,该查询返回scores.unique_uid为该特定测验评分的玩家的每个唯一实例quiz.uid
  3. 使用第三个查询来检索具有唯一性的每组记录的 SUM() 数据scores.unique_uid(我无法成功地与 DISTINCT 查询结合使用)

这是我的PHP代码:

// Query retrieves each unique quiz the player has taken
$ss = sqlQuery("SELECT DISTINCT scores.quiz_uid, quiz.difficulty, quiz.name FROM scores, quiz WHERE scores.user_uid = {$_SESSION['uid']} AND quiz.uid = scores.quiz_uid ORDER BY scores.date_created DESC");
if ( mysql_num_rows( $ss ) > 0 ) {
    while ( $row = mysql_fetch_assoc( $ss ) ){  
        /* Step through each quiz and output name and difficulty */
?>
<h2><?php echo ( $row['name'] ); ?> <span><small>Difficulty: <?php echo( $row['difficulty'] ); ?></small></span></h2>
<?php
        // Query retrieves each unique unique_uid scored (each instance of every quiz)
        $eqs = sqlQuery("SELECT DISTINCT unique_uid FROM scores WHERE quiz_uid = {$row['quiz_uid']} AND user_uid = {$_SESSION['uid']}");

        while ( $eqsrow = mysql_fetch_assoc( $eqs ) ){
            /* Step through each quiz played instance, and output score and other details */

            // Query retrieves SUM()s for total time, total points, total correct responses
            $euqs = sqlQuery('SELECT date_created, ' . 
                'SUM(time) AS times, SUM(points) AS points, SUM(correct) AS ttlcorrect ' .
                "FROM scores WHERE unique_uid = {$eqsrow['unique_uid']} AND user_uid = {$_SESSION['uid']} ");

            // Output the score
            while ( $euqsrow = @mysql_fetch_assoc( $euqs ) ){
?>
<div class="row">
<span class="score"><?php echo( number_format( $euqsrow['points'], 0) ); ?> points</span>
<span class="time"><?php echo( number_format( $euqsrow['times'], 0) ); ?> seconds</span>
<span class="correct"><?php echo( number_format( $euqsrow['ttlcorrect'], 0) ); ?> / 10 correct</span>
<span class="date">Played <?php echo( date( 'F j, Y', strtotime($euqsrow['date_created']) ) ); ?></span>
</div>
<?php
            } // Close euqs while()
        } // close $eqs while()
    } // close $ss while()
} // close if()

以下是每个表的一些示例记录。

测验表:

(uid, category_uid, name, sample, difficulty, date_created, date_updated)
(1, 1, 'Business and Industry', '\0\0', 'Newcomer', '2012-03-15 13:42:30', '2012-03-15 13:42:30'),
(2, 2, 'History', '\0\0', 'Newcomer', '2012-03-15 13:42:30', '2012-03-15 13:42:30'),
(3, 3, 'Sports', '\0\0', 'Newcomer', '2012-03-15 13:42:50', '2012-03-15 13:42:50'),
(4, 4, 'Arts/Entertainment', '\0\0', 'Newcomer', '2012-03-15 13:42:50', '2012-03-15 13:42:50'),
(5, 5, 'Music', '\0\0', 'Newcomer', '2012-03-15 13:43:11', '2012-03-15 13:43:11'),
(6, 6, 'Geography', '\0\0', 'Newcomer', '2012-03-15 13:43:11', '2012-03-15 13:43:11');

成绩表:

(uid, unique_uid, question_uid, quiz_uid, user_uid, answer, correct, points, time, date_created)
(81, '1111334693628', 4, 1, 11, 'Paul''s Valley', '0\0', 0, 2.8, '2012-04-17 13:15:40'),
(82, '1111334693628', 6, 1, 11, 'Bartlesville', '1\0', 9, 2.4, '2012-04-17 13:15:44'),
(83, '1111334693628', 3, 1, 11, 'Shawnee', '1\0', 8, 5.9, '2012-04-17 13:15:51'),
(84, '1111334693628', 40, 1, 11, 'Cimarron Turnpike', '0\0', 0, 4.4, '2012-04-17 13:15:57'),
(85, '1111334693628', 1, 1, 11, 'tow package for trucks', '1\0', 9, 3.9, '2012-04-17 13:16:03'),
(86, '1111334693628', 36, 1, 11, 'aviation', '1\0', 6, 9.0, '2012-04-17 13:16:13'),
(87, '1111334693628', 37, 1, 11, 'Altus', '0\0', 0, 3.0, '2012-04-17 13:16:18'),
(88, '1111334693628', 2, 1, 11, 'Bama Pies', '1\0', 7, 6.1, '2012-04-17 13:16:25'),
(89, '1111334693628', 5, 1, 11, 'Gordon Cooper', '0\0', 0, 2.2, '2012-04-17 13:16:29'),
(90, '1111334693628', 38, 1, 11, 'Bartlesville', '1\0', 9, 2.7, '2012-04-17 13:16:33'),
(91, '1131334773558', 13, 3, 11, 'Jim Thorpe', '1\0', 10, 1.5, '2012-04-18 11:26:09'),
(92, '1131334773558', 49, 3, 11, 'Henry Iba', '1\0', 10, 1.8, '2012-04-18 11:26:12'),
(93, '1131334773558', 17, 3, 11, 'Kelli Litsch', '1\0', 10, 1.9, '2012-04-18 11:26:15'),
(94, '1131334773558', 14, 3, 11, 'Bud Wilkinson', '0\0', 0, 4.4, '2012-04-18 11:26:21'),
(95, '1131334773558', 48, 3, 11, 'Charlie Coe', '1\0', 10, 1.7, '2012-04-18 11:26:25'),
(96, '1131334773558', 50, 3, 11, 'Jim Tatum', '1\0', 8, 4.3, '2012-04-18 11:26:31'),
(97, '1131334773558', 47, 3, 11, 'Bobby Murcer', '0\0', 0, 2.4, '2012-04-18 11:26:34'),
(98, '1131334773558', 15, 3, 11, 'Myron Roderick', '1\0', 9, 3.1, '2012-04-18 11:26:39'),
(99, '1131334773558', 46, 3, 11, 'Tommy McDonald', '1\0', 9, 3.6, '2012-04-18 11:26:44'),
(100, '1131334773558', 16, 3, 11, 'five', '0\0', 0, 2.0, '2012-04-18 11:26:48'),
(101, '1131334773620', 15, 3, 11, 'Myron Roderick', '1\0', 9, 2.4, '2012-04-18 11:27:16'),
(102, '1131334773620', 13, 3, 11, 'Jim Thorpe', '1\0', 10, 1.1, '2012-04-18 11:27:18'),
(103, '1131334773620', 49, 3, 11, 'Henry Iba', '1\0', 10, 1.3, '2012-04-18 11:27:21'),
(104, '1131334773620', 16, 3, 11, 'seven', '1\0', 10, 1.8, '2012-04-18 11:27:25'),
(105, '1131334773620', 46, 3, 11, 'Tommy McDonald', '1\0', 10, 1.4, '2012-04-18 11:27:28'),
(106, '1131334773620', 47, 3, 11, 'Darrell Porter', '1\0', 10, 1.8, '2012-04-18 11:27:31'),
(107, '1131334773620', 50, 3, 11, 'Jim Tatum', '1\0', 9, 2.2, '2012-04-18 11:27:35'),
(108, '1131334773620', 14, 3, 11, 'Benny Owen', '1\0', 9, 2.7, '2012-04-18 11:27:39'),
(109, '1131334773620', 17, 3, 11, 'Kelli Litsch', '1\0', 10, 1.8, '2012-04-18 11:27:42'),
(110, '1131334773620', 48, 3, 11, 'Charlie Coe', '1\0', 10, 1.9, '2012-04-18 11:27:46');
4

2 回答 2

1

使用一个 MySQL 查询怎么样?

SELECT * FROM quiz LEFT JOIN scores ON quiz.uid = scores.quiz_uid

然后只是循环通过它?

于 2012-04-18T19:38:47.853 回答
0

我能够通过使用 GROUP 提出解决方案。对于任何可能感兴趣的人,这就是我所做的:

// Query retrieves each unique play of each quiz the player has scored
$ss = sqlQuery("SELECT quiz.name, quiz.difficulty, scores.unique_uid, scores.quiz_uid, scores.date_created, SUM(scores.time) AS times, SUM(scores.points) AS points, SUM(scores.correct) AS ttlcorrect FROM scores, quiz WHERE scores.user_uid = {$_SESSION['uid']} AND quiz.uid = scores.quiz_uid GROUP BY scores.unique_uid ORDER BY quiz_uid, scores.date_created DESC");

$last_quiz = 0;
if ( mysql_num_rows( $ss ) > 0 ) {
    while ( $row = mysql_fetch_assoc( $ss ) ){  
        /* Step through each play of each quiz */

        if ( $row['quiz_uid'] != $last_quiz ) {
            // Output Details
            $last_quiz = $row['quiz_uid'];
?>
<h2><?php echo ( $row['name'] ); ?> <span><small>Difficulty: <?php echo( $row['difficulty'] ); ?></small></span></h2>
<?php
        }
        // Output Scores
?>
<div class="row">
<span class="score"><?php echo( number_format( $row['points'], 0) ); ?> points</span>
<span class="time"><?php echo( number_format( $row['times'], 0) ); ?> seconds</span>
<span class="correct"><?php echo( number_format( $row['ttlcorrect'], 0) ); ?> / 10 correct</span>
<span class="date">Played <?php echo( date( 'F j, Y', strtotime($row['date_created']) ) ); ?></span>
</div>
<?php
    } // $ss while()
} // close if
?>
于 2012-04-18T19:57:53.883 回答