php - 我应该使用哪个 SQL 请求?
问题描述
我有桌子Skills
和Result
___ Matieres ___ ___ Resultats ___
id (int auto increment) ID (int auto_increment)
Nom (varchar) TIME_OF_INSERTION (datetime current_timestamp)
Categorie (varchar) ID_USER (int)
Active (boolean) ID_MATIERE (int)
RESULTAT (int)
我有这段代码可以根据查询的数据创建一个表单:
$req = $bdd->query(SELECT * FROM Matieres LEFT JOIN Resultats ON Matieres.id = Resultats.ID_MATIERE WHERE Active = TRUE);
$skills = [];
while( $data = $req->fetch()) {
array_push( $skills, [ $data['id'], $data['Nom'], $data['RESULTAT'] ] );
}
function setWidgetValue( $skill ) {
if(is_null($skill[2])) {
$value = 0;
} else {
$value = $skill[2];
}
$widget = "<div class='m-5'><p>".$skill[1]."</p><input type='range' value='" . $value ."' class='form-control-range' min='0' step='1' max='10' id='".$skill[0]."' name='valSkill' onchange=\"MAJ_Value( ".$skill[0].", this.value, " . $_SESSION['id'] . " )\" ></div>";
return $widget;
}
function setAllWidgetValue( $skills ) {
$widget = "<div id='valSkills' >\n";
foreach( $skills as $skill )
$widget .= setWidgetValue( $skill );
$widget .= "</div>";
return $widget;
}
问题是我的输入值应该是0
如果用户还没有发送它们并且如果一个用户发送它就可以正常工作。但是,如果另一个用户尝试访问表单,则输入将具有前一个用户提交的值。
我认为问题出在 SQL 请求中,但我找不到一个完美运行的 :( 我知道我必须传递id
用户的,但不知道在请求中写在哪里
解决方案
一点关于 SQL 的知识
你的表和你的表之间好像有one-many
关系?Matieres
Resultat
SELECT...JOIN
在这种情况下使用语句时,您有效Matieres
地返回Resultat
.
例如:
- 假设你有一个技能/matiere
can touch toes
- 假设有谁拥有该技能的
5
记录Resultat
users
使用您当前的查询结构,您可以执行以下操作:
__SQL:
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat ON Matieres.id = Result.ID_SKILL
__RESULTS:
Resultat.ID_USER Matieres.Nom Resultat.RESULTAT
1 can touch toes 50
2 can touch toes 71
3 can touch toes 23
4 can touch toes 88
5 can touch toes 20
要更改此行为,您需要在ON
子句中指定附加条件:
__SQL:
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
AND Resultat.ID_USER = 1
__RESULTS:
Resultat.ID_USER Matieres.Nom Resultat.RESULTAT
1 can touch toes 50
PHP while 语句回显重复:在此处查看答案以获取更多信息和示例
ON 不是 WHERE
附加条件必须进入ON
子句而不是WHERE
子句的原因是你想要获得每一项Active
技能/matiere,无论是否有人已经获得了Resultat
它。
如果我们将它放入WHERE
子句中,我们会得到:
__SQL:
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
WHERE Resultat.ID_USER = 1
__RESULTS:
Resultat.ID_USER Matieres.Nom Resultat.RESULTAT
1 can touch toes 50
除非您考虑到您拥有多种技能/材料并且用户没有每个技能/材料的记录,否则这似乎还可以......例如:
__TABLES
Matieres Resultat
id Nom ID_USER ID_MATIERE RESULTAT
111 can touch toes 1 111 54
112 can handstand 1 112 60
113 can cartwheel 2 113 72
.
__SQL[1]: {For ID_USER == 1; using ON}
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
AND Resultat.ID_USER = 1
__RESULT[1]:
Matieres Resultat
id Nom ID_USER ID_MATIERE RESULTAT
111 can touch toes 1 111 54
112 can handstand 1 112 60
113 can cartwheel NULL NULL NULL
__SQL[2]: {For ID_USER == 2; using ON}
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
AND Resultat.ID_USER = 2
__RESULT [2]:
Matieres Resultat
id Nom ID_USER ID_MATIERE RESULTAT
111 can touch toes NULL NULL NULL
112 can handstand NULL NULL NULL
113 can cartwheel 2 113 72
__SQL[3]: {For ID_USER == 1; using WHERE}
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
WHERE Resultat.ID_USER = 1
__RESULT[3]:
Matieres Resultat
id Nom ID_USER ID_MATIERE RESULTAT
111 can touch toes 1 111 54
112 can handstand 1 112 60
__SQL[4]: {For ID_USER == 2; using WHERE}
SELECT Resultat.ID_USER, Matieres.Nom, Result.RESULTAT
FROM Matieres
LEFT JOIN Resultat
ON Matieres.id = Result.ID_SKILL
WHERE Resultat.ID_USER = 2
__RESULT[4]:
Matieres Resultat
id Nom ID_USER ID_MATIERE RESULTAT
113 can cartwheel 2 113 72
你的问题
假设
- 您已
user
登录到该网站$_SESSION["id"] == Resultat.ID_USER
- 你想要
SELECT
所有已经Matieres.id && Matieres.Nom
记录Resultat.RESULTAT
的技能Resultat.ID_USER
- 您正在使用
PDO
并且$bdd
是您与数据库的连接
示例代码
// SQL statement using `?` as a placeholder for the users id (from $_SESSION["id"]
// Add: "AND Resultats.ID_USER = ?" to ON clause to limit joined records to currently logged in user
$sql = "
SELECT Matieres.id, Matieres.nom, Resultats.RESULTAT
FROM Skills
LEFT JOIN Resultats ON Matieres.id = Resultats.ID_MATIERE AND Resultats.ID_USER = ?
WHERE Matieres.Active = TRUE
";
$req = $bdd->prepare($sql); // Prepare query
$req->execute([ $_SESSION["id"] ]); // Assign value to place holder and execute query
$skills = [];
while( $data = $req->fetch() ) {
$skills[] = [
"id"=>$data["id"],
"Nom"=>$data["Nom"],
"RESULTAT"=>$data["RESULTAT"]
];
}
function setWidgetValue( $skill ) {
// Set values outside of "widget" string for ease of reading
$value = ( is_null($skill["RESULTAT"]) ) ? 0 : $skill["RESULTAT"]; // Shorthand if statement using the ternary operator
$nom = $skill["Nom"];
$skill_id = $skill["id"];
$user_id = $_SESSION["id"];
// I've separated the code over several lines to make
// it easier to read you can of course change it back!
$widget = "
<div class='m-5'>
<p>{$nom}</p>
<input
type='range'
value='{$value}'
class='form-control-range'
min='0' step='1' max='10'
id='{$skill_id}'
name='valSkill'
onchange=\"MAJ_Value( {$skill_id}, this.value, {$user_id}
)\" >
</div>
";
return $widget;
}
function setAllWidgetValue( $skills ) {
$widget = "<div id='valSkills' >\n";
foreach( $skills as $skill )
$widget .= setWidgetValue( $skill );
$widget .= "</div>";
return $widget;
}
推荐阅读
- botframework - 在哪里可以找到网络聊天的类型值
- android - 如何为自定义 TextInputLayout 设置默认样式
- flutter - 扑; TextField RegExp 文本中不同位置的不同比例
- javascript - Node.js - 即使分配了全局变量,它也会退休
- r - 您如何遍历所有列以在 ggplot 中绘制多个系列?
- rust - 为什么我不能在 NEAR 合约中读取这个 HashMap?
- php - 根据 WooCommerce 结帐中的打开、关闭和休息时间添加具有时间间隔的选择字段
- html - 在页眉和页脚中创建超链接的问题
- c++ - 查找数组中乘积小于等于常数 k 的所有对
- vue.js - Vue Router 最佳实践:在商店或组件中重定向?