0

トリビア クイズ ゲームのこの部分に関連する 2 つのテーブルがscoresありquizます。私は多数の PHP と MySQL のループを入れ子にしましたが、同じ結果を達成するためのより洗練された方法 (そしてできればデータベース クエリの数が少ない) があることを願っています。

どんな提案でも大歓迎です。

以下は、MySQL 構造、PHP コード、およびいくつかのサンプル データです。

テーブルquizには、システム内の各クイズの情報が保持され、クイズごとに 1 つのレコードが保持されます。

  `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には、ユーザーがクイズを行ったときの結果が保持されます。クイズの質問ごとに 1 つのレコード (つまり、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した 1 回を指します。これは、プレイヤーが =1 を 5 回プレイする可能性があることを意味します。これは、表に記録された合計 (5 回 X 10 質問 =) 50 行に対して 5 回quiz.uid異なることを意味します。score.unique_uidscores

私がやろうとしているのは、すべての個別のscores.unique_uidレコード (プレーヤーがスコアを持っているすべてのクイズのリスト) を取得し、10 個のレコードのセット (1 つのクイズ、10 の質問) ごとに集計された結果を調べることです。

私が今やっている方法は次のとおりです。

  1. quiz.uidプレイヤーが獲得した各ユニークを返すクエリをループする
  2. scores.unique_uidその特定のクイズを得点したプレーヤーの一意のインスタンスごとにを返す別のクエリをループするquiz.uid
  3. 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

次のような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 に答える