web-dev-qa-db-ja.com

SubmissionIdでグループ化されたRSForm提出データを取得するにはどうすればよいですか?

3つの列を持つテーブルがあります。SubmissionId、FieldName、FieldValueです。

1)SubmissionId IDの送信を維持します。

2)FieldNameフォームのフィールド名を格納します。

)FieldValueフォームフィールドのフィールド値を格納します。

nameemailstatusの3つのフィールドを持つフォームがあります。私は4つの提出物があります。合計12のエントリがあります。提出物ごとに3つです。

提出物のstatusフィールドが文字列「open」と等しい提出物の3つのレコードを取得するにはどうすればよいですか?

出来ますか?私はたどるクエリですが、「status」フィールドを含むレコードのみを取得することは明らかです。他の2つのフィールドが必要です。

更新しました:

$query
    ->select('a.SubmissionId, a.DateSubmitted, a.status, b.SubmissionId, b.FieldName, b.FieldValue')
    ->from($db->quoteName('#__rsform_submissions', 'a'))
    ->join('INNER', $db->quoteName('#__rsform_submission_values', 'b') . ' ON (' . $db->quoteName('a.SubmissionId') . ' = ' . $db->quoteName('b.SubmissionId') . ')')
    ->where($db->quoteName('b.FieldName') . ' = \'status\' AND ' . $db->quoteName('b.FieldValue') . ' = \'open\'' );
2
George Berkeley

希望する結果を収集するために、実際には同じテーブルで複数の結合を実行する必要はありません。最適なのは "pivot"テクニック です。 rsformの送信データを処理する明確な方法はありません。

_#__rsform_submissions_テーブルには「フォーム」が1つしかない場合もありますが、WHERE句でFormIdを指定する方が堅牢です。 (フォローするために、スニペットで_1_を使用します。)

私が提案する生のクエリは:

_SELECT
    a.SubmissionId,
    a.DateSubmitted,
    a.status,
    MAX(CASE WHEN b.FieldName = 'name' THEN b.FieldValue ELSE NULL END) AS name,
    MAX(CASE WHEN b.FieldName = 'email' THEN b.FieldValue ELSE NULL END) AS email
FROM `#__rsform_submissions` a
INNER JOIN `#__rsform_submission_values` b ON a.SubmissionId = b.SubmissionId
WHERE a.FormId = 1
GROUP BY a.SubmissionId
HAVING MAX(CASE WHEN b.FieldName = 'status' THEN b.FieldValue ELSE NULL END) = 'open'
_

上記は、2つの関連するテーブルを(1回だけ)結合し、SubmissionIdに基づいて送信値をグループ化します。 GROUP BY句は、必要な値を抽出するために特別な処理を必要とする「集約」データ(関連データのクラウド-必要であれば)を作成します。 MAX(CASE...)構文を使用すると、特定の値を取得できます。 HAVING句は、statusの値がopenである送信をチェックします。 SELECT句はnameemailをプルし、結果セットで提供します。

Joomla/PHPコード:

_$query = $db->getQuery(true)
    ->select([
        "a.SubmissionId",
        "a.DateSubmitted",
        "a.status",
        "MAX(CASE WHEN b.FieldName = 'name' THEN b.FieldValue ELSE NULL END) AS name",
        "MAX(CASE WHEN b.FieldName = 'email' THEN b.FieldValue ELSE NULL END) AS email"
    ])
    ->from("#__rsform_submissions a")
    ->innerJoin("#__rsform_submission_values b ON a.SubmissionId = b.SubmissionId")
    ->where("a.FormId = 1")
    ->group("a.SubmissionId")
    ->having("MAX(CASE WHEN b.FieldName = " . $db->q("status") . " THEN b.FieldValue ELSE NULL END) = " . $db->q("open"));

// echo $query->dump();  // uncomment if you want to confirm the rendered query
try {
    $db->setQuery($query);
    echo "<pre>";
    var_dump($db->loadAssocList());
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error');  // never show getMessage() to public
}
_

テストスキーマ:

_CREATE TABLE IF NOT EXISTS `#__rsform_submissions` (
  `SubmissionId` int(11) NOT NULL,
  `FormId` int(11) NOT NULL DEFAULT '0',
  `DateSubmitted` datetime NOT NULL,
  `UserIp` varchar(15) NOT NULL DEFAULT '',
  `Username` varchar(255) NOT NULL DEFAULT '',
  `UserId` text NOT NULL,
  `Lang` varchar(255) NOT NULL,
  `status` tinyint(1) NOT NULL
) ENGINE=InnoDB CHARSET=utf8;

INSERT INTO `#__rsform_submissions` (`SubmissionId`, `FormId`, `DateSubmitted`, `UserIp`, `Username`, `UserId`, `Lang`, `status`) VALUES
(1, 1, '2011-01-01 01:11:11', '60.241.244.9', 'Cam', '0', 'en-GB', 1),
(2, 1, '2012-02-02 02:22:22', '203.59.245.124', 'Pam', '0', 'en-GB', 1),
(3, 1, '2013-03-03 03:33:33', '101.172.255.225', 'Sam', '0', 'en-GB', 1),
(4, 1, '2014-04-04 04:44:44', '55.79.10.25', 'Tam', '0', 'en-GB', 1);

CREATE TABLE IF NOT EXISTS `#__rsform_submission_values` (
  `SubmissionValueId` int(11) NOT NULL AUTO_INCREMENT,
  `FormId` int(11) NOT NULL,
  `SubmissionId` int(11) NOT NULL DEFAULT '0',
  `FieldName` text NOT NULL,
  `FieldValue` text NOT NULL,
  PRIMARY KEY (`SubmissionValueId`),
  KEY `FormId` (`FormId`),
  KEY `SubmissionId` (`SubmissionId`)
) ENGINE=InnoDB CHARSET=utf8;

INSERT INTO `#__rsform_submission_values` (`SubmissionValueId`, `FormId`, `SubmissionId`, `FieldName`, `FieldValue`) VALUES
(1, 1, 1, 'name', 'Cam'),
(2, 1, 1, 'email', '[email protected]'),
(3, 1, 1, 'status', 'open'),
(4, 1, 2, 'name', 'Pam'),
(5, 1, 2, 'email', '[email protected]'),
(6, 1, 2, 'status', 'closed'),
(7, 1, 3, 'name', 'Sam'),
(8, 1, 3, 'email', '[email protected]'),
(9, 1, 3, 'status', 'open'),
(10, 1, 4, 'name', 'Tam'),
(11, 1, 4, 'email', '[email protected]'),
(12, 1, 4, 'status', 'open');
_

出力:

_array(3) {
  [0]=>
  array(5) {
    ["SubmissionId"]=>
    string(1) "1"
    ["DateSubmitted"]=>
    string(19) "2011-01-01 01:11:11"
    ["status"]=>
    string(1) "1"
    ["name"]=>
    string(3) "Cam"
    ["email"]=>
    string(13) "[email protected]"
  }
  [1]=>
  array(5) {
    ["SubmissionId"]=>
    string(1) "3"
    ["DateSubmitted"]=>
    string(19) "2013-03-03 03:33:33"
    ["status"]=>
    string(1) "1"
    ["name"]=>
    string(3) "Sam"
    ["email"]=>
    string(13) "[email protected]"
  }
  [2]=>
  array(5) {
    ["SubmissionId"]=>
    string(1) "4"
    ["DateSubmitted"]=>
    string(19) "2014-04-04 04:44:44"
    ["status"]=>
    string(1) "1"
    ["name"]=>
    string(3) "Tam"
    ["email"]=>
    string(13) "[email protected]"
  }
}
_
2
mickmackusa

はい、どうぞ:

$query->select($db->qn('s.SubmissionId','id'))
        ->select($db->qn('s.DateSubmitted','date'))
        ->select($db->qn('sv.FieldValue','status'))
        ->select($db->qn('nv.FieldValue','name'))
        ->select($db->qn('ev.FieldValue','email'))
        ->from($db->qn('#__rsform_submissions','s'))
        ->leftJoin($db->qn('#__rsform_submission_values','sv').' ON '.$db->qn('sv.SubmissionId').' = '.$db->qn('s.SubmissionId').' AND '.$db->qn('sv.FieldName').' = '.$db->q('status'))
        ->leftJoin($db->qn('#__rsform_submission_values','nv').' ON '.$db->qn('nv.SubmissionId').' = '.$db->qn('s.SubmissionId').' AND '.$db->qn('nv.FieldName').' = '.$db->q('name'))
        ->leftJoin($db->qn('#__rsform_submission_values','ev').' ON '.$db->qn('ev.SubmissionId').' = '.$db->qn('s.SubmissionId').' AND '.$db->qn('ev.FieldName').' = '.$db->q('email'))
        ->where($db->qn('sv.FieldValue').' = '.$db->q('open'));

出力として、必要なデータを含む行ができます。コードは、各行を理解するのに十分簡単だと思います。

1
Alexandr