回答編集履歴

7

追記

2016/11/17 20:04

投稿

退会済みユーザー
test CHANGED
@@ -212,6 +212,8 @@
212
212
 
213
213
  残業時間、深夜勤務時間を算出し、日給を計算
214
214
 
215
+ (多分、MySQLでしか動かないだろうけど...)
216
+
215
217
 
216
218
 
217
219
  ```sql

6

追記

2016/11/17 20:04

投稿

退会済みユーザー
test CHANGED
@@ -183,3 +183,111 @@
183
183
  ![イメージ説明](8afe930b0a1dc1e8d7a2939cc22b48ee.png)
184
184
 
185
185
 
186
+
187
+ #ついでにおまけ
188
+
189
+
190
+
191
+ スタッフテーブルに「時給」を追加
192
+
193
+
194
+
195
+ ```sql
196
+
197
+ CREATE TABLE `Staff` (
198
+
199
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK',
200
+
201
+ `name` varchar(32) DEFAULT NULL COMMENT 'スタッフ名',
202
+
203
+ `salery` int(11) DEFAULT NULL COMMENT '時給',
204
+
205
+ PRIMARY KEY (`id`)
206
+
207
+ ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
208
+
209
+ ```
210
+
211
+
212
+
213
+ 残業時間、深夜勤務時間を算出し、日給を計算
214
+
215
+
216
+
217
+ ```sql
218
+
219
+ SELECT
220
+
221
+ st.name AS 'スタッフ名'
222
+
223
+ , DATE_FORMAT(sf.start, '%Y年%m月%d日') AS '勤務日'
224
+
225
+ , sf.start AS '勤務開始日時'
226
+
227
+ , sf.end AS '勤務終了日時'
228
+
229
+ , TIME_FORMAT(sf.start, '%H:%i') AS '勤務開始時間'
230
+
231
+ , IF(
232
+
233
+ DATEDIFF(sf.end,sf.start)>0
234
+
235
+ , concat(TIME_FORMAT(sf.end, '%H') + 24 * DATEDIFF(sf.end,sf.start), ':', TIME_FORMAT(sf.end, '%i'))
236
+
237
+ , TIME_FORMAT(sf.end, '%H:%i')
238
+
239
+ ) AS '勤務終了時間'
240
+
241
+ , @hour:=HOUR(TIMEDIFF(sf.end,sf.start)) + MINUTE(TIMEDIFF(sf.end,sf.start)) / 60 AS '勤務時間(h)'
242
+
243
+ , @exceed:=IF(
244
+
245
+ HOUR(TIMEDIFF(sf.end,sf.start)) + MINUTE(TIMEDIFF(sf.end,sf.start)) / 60 - 8 > 0
246
+
247
+ , HOUR(TIMEDIFF(sf.end,sf.start)) + MINUTE(TIMEDIFF(sf.end,sf.start)) / 60 - 8
248
+
249
+ , 0
250
+
251
+ ) AS '残業時間(h)'
252
+
253
+ , @night:=HOUR(
254
+
255
+ TIMEDIFF(
256
+
257
+ LEAST(sf.end, DATE_FORMAT(ADDDATE(DATE(sf.start), INTERVAL +1 DAY), '%Y-%m-%d 07:00:00'))
258
+
259
+ , GREATEST(sf.start, STR_TO_DATE(CONCAT(DATE(sf.start), '22:00:00'), '%Y-%m-%d %H:%i:%s'))
260
+
261
+ )
262
+
263
+ )
264
+
265
+ +
266
+
267
+ MINUTE(
268
+
269
+ TIMEDIFF(
270
+
271
+ LEAST(sf.end, DATE_FORMAT(ADDDATE(DATE(sf.start), INTERVAL +1 DAY), '%Y-%m-%d 07:00:00'))
272
+
273
+ , GREATEST(sf.start, STR_TO_DATE(CONCAT(DATE(sf.start), '22:00:00'), '%Y-%m-%d %H:%i:%s'))
274
+
275
+ )
276
+
277
+ ) AS '深夜勤務(h)'
278
+
279
+ , st.salery AS '時給'
280
+
281
+ , FLOOR(@hour * st.salery + @exceed * st.salery * 0.25 + @night * st.salery * 0.25) AS '給与'
282
+
283
+ FROM Shift sf
284
+
285
+ INNER JOIN Staff st ON sf.staff_id = st.id
286
+
287
+ ```
288
+
289
+
290
+
291
+ ![イメージ説明](d5489cb0236a9d4722b6baa49f4270f4.png)
292
+
293
+

5

追記

2016/11/17 20:01

投稿

退会済みユーザー
test CHANGED
@@ -140,6 +140,20 @@
140
140
 
141
141
 
142
142
 
143
+ #以下のコメントに対する回答
144
+
145
+
146
+
147
+ > 取得はそれで大丈夫ですが、表示する場合です。1日は何時から何時まで, 2日は何時から何時まで、という風に。カレンダーのように表示するのもいいですが。
148
+
149
+ 表示する場合は、先ほど行ったように、同じ日にシフトが二つ表示される場合などありませんか?
150
+
151
+
152
+
153
+ > 登録時に1日の25時から26時(UI)で登録したのに、いざ一覧表示を見てみると2日にシフトがある。実質は変わりないのですが、使用するユーザからするとおかしな挙動になりませんか?
154
+
155
+
156
+
143
157
  ```sql
144
158
 
145
159
  SELECT

4

追記

2016/11/17 18:26

投稿

退会済みユーザー
test CHANGED
@@ -133,3 +133,39 @@
133
133
  |:-:|:-:|:-:|:-:|:-:|
134
134
 
135
135
  | 1 | 1 | 2017-01-01 23:00:00 | 2017-01-02 01:00:00 | お客さん |
136
+
137
+
138
+
139
+ ---
140
+
141
+
142
+
143
+ ```sql
144
+
145
+ SELECT
146
+
147
+ st.name AS 'スタッフ名'
148
+
149
+ , DATE_FORMAT(sf.start, '%Y年%m月%d日') AS '勤務日'
150
+
151
+ , TIME_FORMAT(sf.start, '%H:%i') AS '勤務開始時間'
152
+
153
+ , IF(
154
+
155
+ DATEDIFF(sf.end,sf.start)>0
156
+
157
+ , concat(TIME_FORMAT(sf.end, '%H') + 24 * DATEDIFF(sf.end,sf.start), ':', TIME_FORMAT(sf.end, '%i'))
158
+
159
+ , TIME_FORMAT(sf.end, '%H:%i')
160
+
161
+ ) AS '勤務終了時間'
162
+
163
+ FROM Shift sf
164
+
165
+ INNER JOIN Staff st ON sf.staff_id = st.id
166
+
167
+ ```
168
+
169
+ ![イメージ説明](8afe930b0a1dc1e8d7a2939cc22b48ee.png)
170
+
171
+

3

追記

2016/11/17 18:11

投稿

退会済みユーザー
test CHANGED
@@ -98,6 +98,8 @@
98
98
 
99
99
  | 1 | 1 | 2017-01-01 22:00:00 | 2017-01-02 02:00:00 |
100
100
 
101
+ | 1 | 1 | 2017-01-02 22:00:00 | 2017-01-03 02:00:00 |
102
+
101
103
 
102
104
 
103
105
  ##予約テーブル

2

追記

2016/11/17 17:34

投稿

退会済みユーザー
test CHANGED
@@ -29,3 +29,105 @@
29
29
 
30
30
 
31
31
  datetime型で start, datetime型で end を持っていればすむことでは?
32
+
33
+
34
+
35
+ ---
36
+
37
+
38
+
39
+ これで、イメージできるんじゃないかと思いますが。
40
+
41
+
42
+
43
+ #データベース定義
44
+
45
+
46
+
47
+ ##スタッフテーブル
48
+
49
+
50
+
51
+ ```sql
52
+
53
+ CREATE TABLE `Staff` (
54
+
55
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK',
56
+
57
+ `name` varchar(32) DEFAULT NULL COMMENT 'スタッフ名',
58
+
59
+ PRIMARY KEY (`id`)
60
+
61
+ ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
62
+
63
+ ```
64
+
65
+ | id | name |
66
+
67
+ |:-:|:-:|
68
+
69
+ | 1 | スタッフ名 |
70
+
71
+
72
+
73
+ ##シフトテーブル
74
+
75
+
76
+
77
+ ```sql
78
+
79
+ CREATE TABLE `Shift` (
80
+
81
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK',
82
+
83
+ `staff_id` int(11) DEFAULT NULL COMMENT 'スタッフID',
84
+
85
+ `start` datetime DEFAULT NULL COMMENT '勤務開始日時',
86
+
87
+ `end` datetime DEFAULT NULL COMMENT '勤務終了日時',
88
+
89
+ PRIMARY KEY (`id`)
90
+
91
+ ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
92
+
93
+ ```
94
+
95
+ | id | staff_id | start | end |
96
+
97
+ |:-:|:-:|:-:|:-:|
98
+
99
+ | 1 | 1 | 2017-01-01 22:00:00 | 2017-01-02 02:00:00 |
100
+
101
+
102
+
103
+ ##予約テーブル
104
+
105
+
106
+
107
+ ```sql
108
+
109
+ CREATE TABLE `Reserv` (
110
+
111
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK',
112
+
113
+ `staff_id` int(11) DEFAULT NULL COMMENT 'スタッフID',
114
+
115
+ `start` datetime DEFAULT NULL COMMENT '開始日時',
116
+
117
+ `end` datetime DEFAULT NULL COMMENT '終了日時',
118
+
119
+ `name` varchar(32) DEFAULT NULL COMMENT '予約氏名',
120
+
121
+ PRIMARY KEY (`id`)
122
+
123
+ ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
124
+
125
+ ```
126
+
127
+
128
+
129
+ | id | staff_id | start | end | name |
130
+
131
+ |:-:|:-:|:-:|:-:|:-:|
132
+
133
+ | 1 | 1 | 2017-01-01 23:00:00 | 2017-01-02 01:00:00 | お客さん |

1

追記

2016/11/17 17:09

投稿

退会済みユーザー
test CHANGED
@@ -5,3 +5,27 @@
5
5
  ここがすべての問題の元凶でしょう。
6
6
 
7
7
  日毎にテーブルが増えるなんてゆうのは、アンチパターンの代表格です。
8
+
9
+
10
+
11
+ ---
12
+
13
+
14
+
15
+ date(シフトの日付)
16
+
17
+ start(開始時刻)
18
+
19
+ end(終了時刻)
20
+
21
+
22
+
23
+ これが、間違いの元。
24
+
25
+
26
+
27
+ シフトの日付は不要
28
+
29
+
30
+
31
+ datetime型で start, datetime型で end を持っていればすむことでは?