douju2053 2012-04-18 19:29
浏览 49
已采纳

在PHP中结合几个循环MySQL查询

I have two tables that pertain to this part of a trivia quiz game: scores and quiz. I have nested numerous PHP and MySQL loops, and I'm hoping there's a more elegant way (and hopefully, fewer database queries) to achieve the same results.

Any suggestions greatly appreciated.

Below is my MySQL structure, PHP code and some sample data.

Table quiz holds information for each quiz in the system, one record per 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`)

A unique ID, a map to categories table (not relevant here), a name, whether it's a sample quiz or not, a difficulty rating, the date it was first created, and the date it was last updated.

Table scores holds results from when a user takes a quiz, one record per question in the quiz (so, ten rows for a 10-question quiz):

  `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`)

A unique ID for the record, a unique ID for the instance of the quiz being taken, a map to questions table (not relevant here), a map to quiz table, a map to users table (not relevant here), the answer given, whether it was correct or not, the point score awarded, the time in seconds it took for a response, and the time stamp of the record.

Since a player can re-play quizzes, each scores.unique_uid points to a single time playing the quiz. This means a player might play quiz.uid=1 five different times, meaning five different score.unique_uid for a total of (5 times X 10 questions =) 50 rows recorded in the scores table.

What I'm trying to do is retrieve all distinct scores.unique_uid records (a list of every quiz the player has a score for) and then look at some tabulated results for each set of 10 records (one quiz, 10 questions).

The way I'm doing it now is:

  1. looping through a query that returns each unique quiz.uid the player has scored
  2. looping through another query that returns the scores.unique_uid for each unique instance of the player scoring that particular quiz quiz.uid
  3. using a third query to retrieve the SUM() data for each set of records with unique scores.unique_uid (I couldn't successfully combined with the DISTINCT query)

Here is my PHP code:

// 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()

Here are some sample records for each table.

quiz table:

(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');

scores table:

(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');
  • 写回答

2条回答 默认 最新

  • dongyu1979 2012-04-18 19:57
    关注

    I was able to come up with a solution by using GROUP. For anyone that might be interested, here's what I did:

    // 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
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.