0

4 つのテーブルを使用してレポートを生成する必要があり、多くの結合を試みましたが、間違った値が得られました :(

誰かが私を助けてくれることを願っています。

StaffAssign テーブル:

----------------------------
| Tid | StaffId | Planned  |
----------------------------
| 123 |   2     | 10:00:00 |
| 123 |   4     | 05:00:00 |
| 124 |   2     | 09:00:00 |
----------------------------

ActualEffort テーブル:

--------------------------------------------
| 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|
--------------------------------------------

ProjectList テーブル:

-------------------
| ProjectId | Tid |
-------------------
|    1      | 123 |
|    2      | 124 |
-------------------

ProjectName テーブル:

-------------------
| 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 |
---------------------------------------------

私は非常に混乱しています。結合のどこが間違っているのかわかりません。

誰かが私を助けてください、私はこれに打たれました。

4

3 に答える 3

2

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 |
+---------------------+---------------------+

のタイプActualEffortlogdateフィールドは日付です。値「2012-09-01」は「2012-09-01 08:00:00」よりも小さいです。したがって、この条件を変更するか、DATE 関数を使用してください -

WHERE
  E.logdate BETWEEN
  DATE(FROM_UNIXTIME('1346475600')) AND DATE(FROM_UNIXTIME('1348290000'))

(編集)

1 つには、列のみを結合するStaffAssignと、特にミニデカルト積が得られます。これは、両方のテーブルにそれを含む複数の行が含まれており、1:1 またはせいぜい 1:1 を確立するための他の特定の条件がないためです。 、行間の 1:N 関係。ActualEffortTidTid=123Tid

しかし、実際には、1:N はどちらも行いません。デカルト積の効果は得られませんが、一方の値が重複し、その結果、歪んだ SUM になります。

したがって、データ内StaffAssignと内のデータをActualEffort別々に集計してから、次のように結合する必要があります。

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;
于 2012-09-24T06:31:52.907 に答える
1

SQL にエラーがあります: p.id ではなく p.ProjectID に参加したくありません

于 2012-09-24T06:11:31.640 に答える
0

このクエリを試してください

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が存在する必要があります。

于 2012-09-24T05:54:50.353 に答える