1

特定の日に従業員が働いた合計時間を計算するために、一種の複雑な mysql クエリに取り組んでいます。一部の従業員には正しく機能しますが、他の従業員には機能しません。私が話していることを簡単に理解できるように、SQL Fiddle を作成しました。 http://sqlfiddle.com/#!2/6439f/1/0

データ:

CREATE TABLE punches 
(
     PunchID int auto_increment primary key, 
     EmpID varchar(6),
     Name varchar(20), 
     PunchDateTime DateTime,
     PunchEvent varchar(20),
     `In-Out` int
);    

INSERT INTO punches
(EmpID, Name, PunchDateTime, PunchEvent, `In-Out`)
VALUES
('0538', 'ROXANNE NIESEN', '2013-06-17 07:27:48', 'clockin', 1),
('0538', 'ROXANNE NIESEN', '2013-06-17 16:57:30', 'clockout', 0),
('1102', 'JEFFERY POTTER', '2013-06-17 07:29:44', 'clockin', 1),
('1102', 'JEFFERY POTTER', '2013-06-17 16:29:57', 'clockout', 0),
('1588', 'BRUCE COLEMAN', '2013-06-17 06:20:48', 'clockin', 1),
('1588', 'BRUCE COLEMAN', '2013-06-17 12:15:18', 'breakout', 0),
('1588', 'BRUCE COLEMAN', '2013-06-17 12:43:58', 'breakin', 1),
('1588', 'BRUCE COLEMAN', '2013-06-17 17:00:37', 'clockout', 0);

クエリ:

SELECT Name, DATE_FORMAT(p.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
TIME(SUM(p.PunchDateTime * (1 - 2 * `p`.`In-Out`))) AS 'Hours Worked Time',
SUM(p.PunchDateTime * (1 - 2 * `p`.`In-Out`)) AS 'Hours Worked',
SUM(UNIX_TIMESTAMP(p.PunchDateTime*(1-2*`p`.`In-Out`)))/3600 AS 'Hours Worked Decimal'
FROM punches p
WHERE DATE(p.PunchDateTime) = '2013-06-17'
GROUP BY DATE(p.PunchDateTime), EmpID

結果:

|           NAME | PUNCH DATE |              HOURS WORKED TIME | HOURS WORKED | HOURS WORKED DECIMAL |
------------------------------------------------------------------------------------------------------
| ROXANNE NIESEN | 06-17-2013 |                         (null) |        92982 |          380968.9583 |
| JEFFERY POTTER | 06-17-2013 | January, 01 1970 09:00:13+0000 |        90013 |          380968.4992 |
|  BRUCE COLEMAN | 06-17-2013 | January, 01 1970 10:51:49+0000 |       105149 |          761933.2653 |

Roxanne の最初の結果は時間を返す必要があり、NULL を返します。Jeffery の 2 つ目は正しく機能しています。ブルースとの 3 番目の時間は戻りますが、私が計算した時間は間違っていました。ここで何が起こっているか知っている人はいますか?ありがとうマイク

4

4 に答える 4

1

世界で最も醜いクエリの出場者として....

SELECT U.Name, U.`Punch Date`, SEC_TO_TIME(SUM(U.delta)) FROM
(
(
SELECT `enter`.Name, `enter`.PunchDateTime AS `time`,
DATE_FORMAT(`enter`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
TIMESTAMPDIFF(SECOND, `enter`.PunchDateTime, '2003-05-01 00:00:00') AS `delta`


FROM Punches AS `enter`
WHERE `enter`.`In-Out` = 1
)
UNION
(
SELECT `leave`.Name, `leave`.PunchDateTime AS `time`,
DATE_FORMAT(`leave`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
-TIMESTAMPDIFF(SECOND, `leave`.PunchDateTime, '2003-05-01 00:00:00') AS `delta`


FROM Punches AS `leave`
WHERE `leave`.`In-Out` = 0  
)
) AS U
GROUP BY U.Name,U.`Punch Date`

これを SQLFiddle で実行すると、次の結果が得られます。

NAME PUNCH DATE SEC_TO_TIME(SUM(U.DELTA))
ブルース・コールマン 06-17-2013 10:11:09
ジェフリー・ポッター 2013 年 6 月 17 日 09:00:13
ロクサーヌ・ニーセン 06-17-2013 09:29:42

毎日の作業分数に対応します。

は、日中のブレイクアウトの数に関係なく処理する必要があることに注意してください。それは夜に働く人々を扱いません(つまり、その日にチェックインし、次の日にチェックアウトします)。

于 2013-06-25T16:13:59.413 に答える
0

あなたのデータを見ると、あなたのクエリは私には不可能に見えます。おそらくサブクエリで実行できますが、それが私だったら、アプリケーションで計算します。出勤と退勤のタイムスタンプが同じ列にある場合は、はるかに簡単になります。ただし、このようなイベントを挿入すると、最初にクロックインを挿入し、後で同じレコードをクロックアウト時間で更新することになります。

現在のレイアウトでは、従業員ごとに、特定の日のイベントを選択して時間を計算できます。イベントの順序を確認し、何らかの理由でクロックイン イベントとクロックアウト イベントが欠落している場合に対処するようにしてください。

最後の部分は、SQL ステートメントでどのように実行できるかわかりません。

更新: In-Out についてのあなたの考えがわかりましたが、実際にはそれは失敗の証拠ではありません。良いハック - ええ、でも私が頼りにするものではありません。

于 2013-06-25T15:33:58.603 に答える
0

+------------+----------------+---------------------------------- +--------------+----------------------+
| 名前 | パンチ日 | 時間 労働時間 | 労働時間 | 労働時間
+------------+----------------+---------------------------------- +--------------+----------------------+
| ロクサーヌ・ニーセン | 2013 年 6 月 17 日 | ヌル | 92982 | 380974.9583 |
| | ジェフリー・ポッター | 2013 年 6 月 17 日 | 09:00:13 | 90013 | 380974.4992 |
| | ブルース・コールマン | 2013 年 6 月 17 日 | 10:51:49 | 105149 | 761945.2653 | +------------+----------------+---------------------------------- +--------------------+----------------------+

セットで 3 行、5 つの警告 (0.00 秒)

mysql> 警告を表示します。+---------+------+-------------------------------- -------------+
| レベル | コード | メッセージ |
+---------+------+-------------------------------- -------------+
| 警告 | 1292年 | 日時の値が正しくありません: '-20130617072748' |
| | 警告 | 1292年 | 日時の値が正しくありません: '-20130617072944' |
| | 警告 | 1292年 | 日時の値が正しくありません: '-20130617062048' |
| | 警告 | 1292年 | 日時の値が正しくありません: '-20130617124358' |
| | 警告 | 1292年 | 誤った時刻値が切り捨てられました: '92982' |
+---------+------+-------------------------------- --------------+ セットで 5 行 (0.00 秒)

フォーマットが悪くてすみません

于 2013-06-25T15:49:03.380 に答える