连接表后获取错误的值-MySQL-PHP

连接表后获取错误的值-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 | -------------------

我必须使用4个表生成报告,我尝试了很多联接,但得到了错误的值:(

希望有人能帮助我

StaffAssign表格:

----------------------------
| 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-For
Tid=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-For
Tid=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是的,在这种情况下可以省略“按项目分组”。