连接表后获取错误的值-MySQL-PHP
我必须使用4个表生成报告,我尝试了很多联接,但得到了错误的值:( 希望有人能帮助我 StaffAssign表格:连接表后获取错误的值-MySQL-PHP,php,mysql,sql,join,Php,Mysql,Sql,Join,我必须使用4个表生成报告,我尝试了很多联接,但得到了错误的值:( 希望有人能帮助我 StaffAssign表格: ---------------------------- | Tid | StaffId | Planned | ---------------------------- | 123 | 2 | 10:00:00 | | 123 | 4 | 05:00:00 | | 124 | 2 | 09:00:00 | -------------------
----------------------------
| Tid | StaffId | Planned |
----------------------------
| 123 | 2 | 10:00:00 |
| 123 | 4 | 05:00:00 |
| 124 | 2 | 09:00:00 |
----------------------------
实际值表:
--------------------------------------------
| Tid | StaffId | ActualEffort | logdate |
--------------------------------------------
| 123 | 2 | 05:00:00 |2012-09-01|
| 123 | 4 | 05:00:00 |2012-09-01|
| 123 | 2 | 06:00:00 |2012-09-03|
| 124 | 2 | 09:00:00 |2012-09-04|
--------------------------------------------
项目列表表:
-------------------
| ProjectId | Tid |
-------------------
| 1 | 123 |
| 2 | 124 |
-------------------
项目名称表:
-------------------
| Id | name |
-------------------
| 1 | project1 |
| 2 | project2 |
-------------------
下面是我正在使用的查询:
SELECT P.id AS projectid,P.name,
SEC_TO_TIME(SUM(TIME_TO_SEC(A.planned)))planned,SEC_TO_TIME(SUM(TIME_TO_SEC(E.actualeffort)))actual FROM actualeffort E
INNER JOIN staffassign A ON A.tid = E.tid
INNER JOIN projectlist L ON L.tid = A.tid
INNER JOIN projectname P ON P.id = L.projectid
WHERE E.logdate BETWEEN FROM_UNIXTIME('1346475600') AND FROM_UNIXTIME('1348290000')
GROUP BY P.id
我明白了:
---------------------------------------------
| projectid | name | planned | actual |
---------------------------------------------
| 1 | project1 | 15:00:00| 12:00:00 |
| 2 | project2 | 09:00:00| 09:00:00 |
---------------------------------------------
但它应该是这样的:
---------------------------------------------
| projectid | name | planned | actual |
---------------------------------------------
| 1 | project1 | 15:00:00| 16:00:00 |
| 2 | project2 | 09:00:00| 09:00:00 |
---------------------------------------------
我很困惑,我不知道连接哪里出了问题
有人请帮帮我,我被这个打动了。试试这个查询
SELECT P.id AS projectid,P.name,
SEC_TO_TIME(SUM(TIME_TO_SEC(A.planned)))planned,SEC_TO_TIME(SUM(TIME_TO_SEC(E.actualeffort)))actual FROM actualeffort E
INNER JOIN staffassign A ON A.tid = E.tid
INNER JOIN projectlist L ON L.tid = A.tid
INNER JOIN projectlist L ON L.tid = E.tid // you have not added this line
INNER JOIN projectname P ON P.id = L.projectid
WHERE E.logdate BETWEEN FROM_UNIXTIME('1346475600') AND FROM_UNIXTIME('1348290000')
GROUP BY P.id
应该存在L
和E
之间的联接。尝试此查询
SELECT P.id AS projectid,P.name,
SEC_TO_TIME(SUM(TIME_TO_SEC(A.planned)))planned,SEC_TO_TIME(SUM(TIME_TO_SEC(E.actualeffort)))actual FROM actualeffort E
INNER JOIN staffassign A ON A.tid = E.tid
INNER JOIN projectlist L ON L.tid = A.tid
INNER JOIN projectlist L ON L.tid = E.tid // you have not added this line
INNER JOIN projectname P ON P.id = L.projectid
WHERE E.logdate BETWEEN FROM_UNIXTIME('1346475600') AND FROM_UNIXTIME('1348290000')
GROUP BY P.id
应该存在
L
和E
之间的连接。您的SQL中有一个错误:
您不想加入p.ProjectID而不是p.id您的SQL中有一个错误:
您不想加入p.ProjectID而不是p.id,WHERE筛选器可能错误。请注意,条件中的第一个日期时间从'08:00:00'开始-
SELECT FROM_UNIXTIME('1346475600') dt1, FROM_UNIXTIME('1348290000') dt2;
+---------------------+---------------------+
| dt1 | dt2 |
+---------------------+---------------------+
| 2012-09-01 08:00:00 | 2012-09-22 08:00:00 |
+---------------------+---------------------+
actualefort
logdate
字段的类型为日期;值“2012-09-01”小于“2012-09-01 08:00:00”。因此,请更改此条件或使用日期函数-
WHERE
E.logdate BETWEEN
DATE(FROM_UNIXTIME('1346475600')) AND DATE(FROM_UNIXTIME('1348290000'))
(已编辑) 首先,当您仅在
Tid
列上加入StaffAssign
和actualefort
时,您会得到一个mini-ForTid=123
,因为这两个表都包含多个具有Tid
的行,并且没有其他特定条件在这两个表之间建立1:1或至多1:N关系排成一排
但事实上,1:N也不行:虽然它不会给你笛卡尔积效应,但它会在一边产生重复的值,结果是一个扭曲的和
因此,StaffAssign
中的数据和actualefort
中的数据必须分别聚合,然后合并,如下所示:
SELECT
pl.ProjectId,
pn.name,
sa.Planned,
ae.ActualEffort
FROM ProjectList pl
JOIN ProjectName pn
ON pn.Id = pl.ProjectId
LEFT JOIN (SELECT Tid, SEC_TO_TIME(SUM(TIME_TO_SEC(Planned))) Planned FROM StaffAssign GROUP BY Tid) sa
ON sa.Tid = pl.Tid
LEFT JOIN (SELECT Tid, SEC_TO_TIME(SUM(TIME_TO_SEC(ActualEffort))) ActualEffort FROM ActualEffort GROUP BY Tid) ae
ON ae.Tid = pl.Tid
GROUP BY ProjectId;
WHERE筛选器可能错误。请注意,条件中的第一个日期时间从“08:00:00”开始-
SELECT FROM_UNIXTIME('1346475600') dt1, FROM_UNIXTIME('1348290000') dt2;
+---------------------+---------------------+
| dt1 | dt2 |
+---------------------+---------------------+
| 2012-09-01 08:00:00 | 2012-09-22 08:00:00 |
+---------------------+---------------------+
actualefort
logdate
字段的类型为日期;值“2012-09-01”小于“2012-09-01 08:00:00”。因此,请更改此条件或使用日期函数-
WHERE
E.logdate BETWEEN
DATE(FROM_UNIXTIME('1346475600')) AND DATE(FROM_UNIXTIME('1348290000'))
(已编辑) 首先,当您仅在
Tid
列上加入StaffAssign
和actualefort
时,您会得到一个mini-ForTid=123
,因为这两个表都包含多个具有Tid
的行,并且没有其他特定条件在这两个表之间建立1:1或至多1:N关系排成一排
但事实上,1:N也不行:虽然它不会给你笛卡尔积效应,但它会在一边产生重复的值,结果是一个扭曲的和
因此,StaffAssign
中的数据和actualefort
中的数据必须分别聚合,然后合并,如下所示:
SELECT
pl.ProjectId,
pn.name,
sa.Planned,
ae.ActualEffort
FROM ProjectList pl
JOIN ProjectName pn
ON pn.Id = pl.ProjectId
LEFT JOIN (SELECT Tid, SEC_TO_TIME(SUM(TIME_TO_SEC(Planned))) Planned FROM StaffAssign GROUP BY Tid) sa
ON sa.Tid = pl.Tid
LEFT JOIN (SELECT Tid, SEC_TO_TIME(SUM(TIME_TO_SEC(ActualEffort))) ActualEffort FROM ActualEffort GROUP BY Tid) ae
ON ae.Tid = pl.Tid
GROUP BY ProjectId;
尝试联接表中所有匹配的列。我现在尝试联接所有匹配的列,但结果又错了:(因此,现在您必须手动联接各个表并检查结果…:(尝试联接表中所有匹配的列。我现在尝试联接所有匹配的列,结果又错了:(因此,现在您必须手动将各个表相互连接起来,并检查结果…:(哦,这是我在so中犯的错误。我现在编辑了它。请帮助:(哦,这是我在so中犯的错误。我现在编辑了它。请帮助:(我自由地编辑了您的答案,我将发布我自己的内容。请随时回滚我的更改或编辑您认为合适的内容。此外,我认为您不需要按ProjectId进行最后的
分组。或者,如果每个ProjectId
可能有一个以上的Tid,您可能需要合计(sa.Planned)
和SUM(ae.actualefort)
工作完美:)非常感谢@AndriyM:)@AndriyM是的,在这种情况下,“按项目分组”可以省略。我用我即将发布的内容自由编辑了您的答案。请随时回滚我的更改或根据您认为合适的方式进行编辑。此外,我认为您不需要最终的按项目分组。或者,如果每个项目可能有多个Tid
ectId
,您可能需要SUM(sa.Planned)
和SUM(ae.actualefort)
。工作完美:)非常感谢@AndriyM:)@AndriyM是的,在这种情况下可以省略“按项目分组”。