3つの列を持つテーブルがあります。SubmissionId、FieldName、FieldValueです。
1)SubmissionId IDの送信を維持します。
2)FieldNameフォームのフィールド名を格納します。
)FieldValueフォームフィールドのフィールド値を格納します。
name
、email
、status
の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\'' );
希望する結果を収集するために、実際には同じテーブルで複数の結合を実行する必要はありません。最適なのは "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句はname
とemail
をプルし、結果セットで提供します。
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]"
}
}
_
はい、どうぞ:
$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'));
出力として、必要なデータを含む行ができます。コードは、各行を理解するのに十分簡単だと思います。