无法在具有 3 个 JOIN 的 sql 上列出一对多关系的列数据
can't list column data from one to many relation on sql with 3 JOINs
我有 4 tables -
CREATE TABLE `group_user` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`accepted` tinyint(4) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `group_table` (
`id` int(11) NOT NULL,
`groupName` varchar(255) NOT NULL,
`owner` varchar(255) NOT NULL,
`date_dreated` datetime NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `training` (
`id` int(11) NOT NULL,
`groupName` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
`sessDate` date NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `session_plan` (
`id` int(11) NOT NULL,
`training_id` int(11) NOT NULL,
`workout_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
group_table
保存每个组的id和名称,
group_user
保存哪些用户是哪些组的成员,
training
保存会话的 ID 和日期以及它们属于哪个组
session_plan
保存在任何给定日期的特定会话的个人锻炼。锻炼 ID 来自名为 workout_title
的 table,它位于下方并包含锻炼的名称,我在下面列出了它,但现在我只是想获取 workout_id
的列表
session_plan
中可能有很多结果与其他 3 table 个结果相匹配。
我确实将此设置为逗号分隔列表,但被告知要规范化我的 tables,
虽然这确实解决了我遇到的一些其他问题,但我现在有一个问题,对于 session_plan
中的每个结果,它都会重复之前的结果,然后只添加 [=16] 中的下一个项目=].
我目前的代码是
$accepted = true;
$ps = $db_conx->prepare("
SELECT u.group_id
, g.groupName
, t.sessDate
, s.workout_id
FROM group_user u
JOIN group_table g
ON u.group_id = g.id
JOIN training t
ON g.groupName = t.groupName
JOIN session_plan s
ON t.id = s.training_id
WHERE g.user_id = ?
&& u.accepted = ?
");
$ps->bind_param("ii", $id, $accepted);
$ps->execute();
$result = $ps->get_result();
while ($row = mysqli_fetch_assoc($result)) {
$testGroupName = $row['groupName'];
$testGroupId = $row['group_id'];
$testSessDate = $row['sessDate'];
$testPlan = $row['workout_id'];
$workout_plan .= " + " .$testPlan;
$testSession .= $testGroupId. " : " .$testGroupName. "<br/>" .$testSessDate. " - " .$workout_plan. "<br/>";
}
$id
在页面上方进一步定义。
我要找的是:
1 : TheBestGroup
2020-12-05 - + 1 + 2
1 : TheBestGroup
2020-12-04 - + 4
但我得到的是:
1 : TheBestGroup
2020-12-05 - + 1
1 : TheBestGroup
2020-12-05 - + 1 + 2
1 : TheBestGroup
2020-12-04 - + 1 + 2 + 4
我是规范化和 table JOIN 的新手,所以不确定我是否错误地使用了一个或另一个或两者。
我在这里搜索了一个答案,虽然有类似的答案,但我找不到经常用我无法理解的编码语言解决我的问题的答案。
从逻辑上讲,我认为问题是 while 循环每次通过时只会从每个 table 中选择一个结果,然后 $workout_plan .= " + " .$testPlan;
将其存储到下一个 运行 通过循环,我尝试在循环外添加 $workout_plan = "";
和 unset($workout_plan)
但得到了相同的结果。如果我删除 $workout_plan .= " + " .$testPlan;
结果如下:
1 : TheBestGroup
2020-12-05 - 1
1 : TheBestGroup
2020-12-05 - 2
1 : TheBestGroup
2020-12-04 - 4
我只是不确定如何从 session_plan
的每一行中为其他人获取所有相关条目。
您只需要逻辑来区分何时要将 workout_id
添加到 testSession
,以及何时移动到新的组或日期。
类似...
$testGroupId = "";
$testSessDate = "";
$testSession = "";
while ($row = mysqli_fetch_assoc($result)) {
// If this row's Group and Date are the same as the preceding row...
// - Add this row's WorkoutId to the testSession and move to the next row
if (($testGroupId == $row['group_id']) && ($testSessDate == $row['sessDate']))
$testSession .= " + " .$row['workout_id'];
continue;
// If this row's Group or Date are Different from the preceding row...
// - Add a break to the end of the previous testSession
// - Do something with the previous testSession
// - Start a new testSession with the current row's values
$testSession .= "<br/>";
# Code to use the previous testSession goes here
$testGroupName = $row['groupName'];
$testGroupId = $row['group_id'];
$testSessDate = $row['sessDate'];
$testPlan = $row['workout_id'];
$testSession = $testGroupId. " : " .$testGroupName. "<br/>" .$testSessDate. " - " .$testPlan. "<br/>";
}
// The very last Group/Date combination won't have been processed by the While loop
// So, process it here
$testSession .= "<br/>";
# Code to use the previous testSession goes here
我有 4 tables -
CREATE TABLE `group_user` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`accepted` tinyint(4) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `group_table` (
`id` int(11) NOT NULL,
`groupName` varchar(255) NOT NULL,
`owner` varchar(255) NOT NULL,
`date_dreated` datetime NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `training` (
`id` int(11) NOT NULL,
`groupName` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
`sessDate` date NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `session_plan` (
`id` int(11) NOT NULL,
`training_id` int(11) NOT NULL,
`workout_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
group_table
保存每个组的id和名称,
group_user
保存哪些用户是哪些组的成员,
training
保存会话的 ID 和日期以及它们属于哪个组
session_plan
保存在任何给定日期的特定会话的个人锻炼。锻炼 ID 来自名为 workout_title
的 table,它位于下方并包含锻炼的名称,我在下面列出了它,但现在我只是想获取 workout_id
的列表
session_plan
中可能有很多结果与其他 3 table 个结果相匹配。
我确实将此设置为逗号分隔列表,但被告知要规范化我的 tables,
虽然这确实解决了我遇到的一些其他问题,但我现在有一个问题,对于 session_plan
中的每个结果,它都会重复之前的结果,然后只添加 [=16] 中的下一个项目=].
我目前的代码是
$accepted = true;
$ps = $db_conx->prepare("
SELECT u.group_id
, g.groupName
, t.sessDate
, s.workout_id
FROM group_user u
JOIN group_table g
ON u.group_id = g.id
JOIN training t
ON g.groupName = t.groupName
JOIN session_plan s
ON t.id = s.training_id
WHERE g.user_id = ?
&& u.accepted = ?
");
$ps->bind_param("ii", $id, $accepted);
$ps->execute();
$result = $ps->get_result();
while ($row = mysqli_fetch_assoc($result)) {
$testGroupName = $row['groupName'];
$testGroupId = $row['group_id'];
$testSessDate = $row['sessDate'];
$testPlan = $row['workout_id'];
$workout_plan .= " + " .$testPlan;
$testSession .= $testGroupId. " : " .$testGroupName. "<br/>" .$testSessDate. " - " .$workout_plan. "<br/>";
}
$id
在页面上方进一步定义。
我要找的是:
1 : TheBestGroup 2020-12-05 - + 1 + 2
1 : TheBestGroup 2020-12-04 - + 4
但我得到的是:
1 : TheBestGroup 2020-12-05 - + 1
1 : TheBestGroup 2020-12-05 - + 1 + 2
1 : TheBestGroup 2020-12-04 - + 1 + 2 + 4
我是规范化和 table JOIN 的新手,所以不确定我是否错误地使用了一个或另一个或两者。
我在这里搜索了一个答案,虽然有类似的答案,但我找不到经常用我无法理解的编码语言解决我的问题的答案。
从逻辑上讲,我认为问题是 while 循环每次通过时只会从每个 table 中选择一个结果,然后 $workout_plan .= " + " .$testPlan;
将其存储到下一个 运行 通过循环,我尝试在循环外添加 $workout_plan = "";
和 unset($workout_plan)
但得到了相同的结果。如果我删除 $workout_plan .= " + " .$testPlan;
结果如下:
1 : TheBestGroup 2020-12-05 - 1
1 : TheBestGroup 2020-12-05 - 2
1 : TheBestGroup 2020-12-04 - 4
我只是不确定如何从 session_plan
的每一行中为其他人获取所有相关条目。
您只需要逻辑来区分何时要将 workout_id
添加到 testSession
,以及何时移动到新的组或日期。
类似...
$testGroupId = "";
$testSessDate = "";
$testSession = "";
while ($row = mysqli_fetch_assoc($result)) {
// If this row's Group and Date are the same as the preceding row...
// - Add this row's WorkoutId to the testSession and move to the next row
if (($testGroupId == $row['group_id']) && ($testSessDate == $row['sessDate']))
$testSession .= " + " .$row['workout_id'];
continue;
// If this row's Group or Date are Different from the preceding row...
// - Add a break to the end of the previous testSession
// - Do something with the previous testSession
// - Start a new testSession with the current row's values
$testSession .= "<br/>";
# Code to use the previous testSession goes here
$testGroupName = $row['groupName'];
$testGroupId = $row['group_id'];
$testSessDate = $row['sessDate'];
$testPlan = $row['workout_id'];
$testSession = $testGroupId. " : " .$testGroupName. "<br/>" .$testSessDate. " - " .$testPlan. "<br/>";
}
// The very last Group/Date combination won't have been processed by the While loop
// So, process it here
$testSession .= "<br/>";
# Code to use the previous testSession goes here