私はこのように見えるユーザーのチェックインとアウトの時間の表( "lms_attendance")を持っています。
id user time io (enum)
1 9 1370931202 out
2 9 1370931664 out
3 6 1370932128 out
4 12 1370932128 out
5 12 1370933037 in
このテーブルのビューを作成して、ユーザーIDごとに最新のレコードのみを出力するようにしながら、 "in"または "out"の値を指定します。
id user time io
2 9 1370931664 out
3 6 1370932128 out
5 12 1370933037 in
私は今のところかなり親密です、しかし私はビューがサブクエリを受け入れないことに気づきました、それはそれをずっと難しくしています。私が得た最も近いクエリは次のとおりです。
select
`lms_attendance`.`id` AS `id`,
`lms_attendance`.`user` AS `user`,
max(`lms_attendance`.`time`) AS `time`,
`lms_attendance`.`io` AS `io`
from `lms_attendance`
group by
`lms_attendance`.`user`,
`lms_attendance`.`io`
しかし私が得るものは:
id user time io
3 6 1370932128 out
1 9 1370931664 out
5 12 1370933037 in
4 12 1370932128 out
どれが近いですか、しかし完璧ではありません。最後のgroup byはそこにあってはいけないことを私は知っていますが、それがなければ、それは最新の時間を返しますが、それは相対的なIO値ではありません。
何か案は?ありがとうございます。
クエリ:
SELECT t1.*
FROM lms_attendance t1
WHERE t1.time = (SELECT MAX(t2.time)
FROM lms_attendance t2
WHERE t2.user = t1.user)
結果:
| ID | USER | TIME | IO |
--------------------------------
| 2 | 9 | 1370931664 | out |
| 3 | 6 | 1370932128 | out |
| 5 | 12 | 1370933037 | in |
毎回動作するつもりの解決策:
SELECT t1.*
FROM lms_attendance t1
WHERE t1.id = (SELECT t2.id
FROM lms_attendance t2
WHERE t2.user = t1.user
ORDER BY t2.id DESC
LIMIT 1)
これは一般的なので、車輪の再発明を試みる必要はありません グループあたりの最大数の問題 。とても良い 解決策が提示されている 。
私は副問い合わせなしで最も単純化された解決法( SQLFiddleを見てください、Justinのものを更新しました を参照してください)(ビューで使うのが簡単です):
SELECT t1.*
FROM lms_attendance AS t1
LEFT OUTER JOIN lms_attendance AS t2
ON t1.user = t2.user
AND (t1.time < t2.time
OR (t1.time = t2.time AND t1.Id < t2.Id))
WHERE t2.user IS NULL
これは、同じグループ内に同じ最大値を持つ2つの異なるレコードがある場合にも機能します - (t1.time = t2.time AND t1.Id < t2.Id)
のトリックのおかげで。私がここでやっているのは、同じユーザーの2つのレコードが同じ時間を持つ場合に、必ず1つだけが選択されるようにすることです。基準がId
であるかそれ以外のものであるかは実際には問題ではありません。基本的に一意であることが保証されている基準であれば、ここで仕事ができます。
@TMS回答に基づいて、私は副問い合わせを必要としないのでそれが好きですが、私は'OR'
の部分を省略することは十分で理解して読むのがはるかに簡単になると思います。
SELECT t1.*
FROM lms_attendance AS t1
LEFT JOIN lms_attendance AS t2
ON t1.user = t2.user
AND t1.time < t2.time
WHERE t2.user IS NULL
nULL時間のある行に興味がない場合は、WHERE
句でそれらをフィルタリングできます。
SELECT t1.*
FROM lms_attendance AS t1
LEFT JOIN lms_attendance AS t2
ON t1.user = t2.user
AND t1.time < t2.time
WHERE t2.user IS NULL and t1.time IS NOT NULL
すでに解決されていますが、記録のためだけに、もう2つのアプローチは2つのビューを作成することです。
CREATE TABLE lms_attendance
(id int, user int, time int, io varchar(3));
CREATE VIEW latest_all AS
SELECT la.user, max(la.time) time
FROM lms_attendance la
GROUP BY la.user;
CREATE VIEW latest_io AS
SELECT la.*
FROM lms_attendance la
JOIN latest_all lall
ON lall.user = la.user
AND lall.time = la.time;
INSERT INTO lms_attendance
VALUES
(1, 9, 1370931202, 'out'),
(2, 9, 1370931664, 'out'),
(3, 6, 1370932128, 'out'),
(4, 12, 1370932128, 'out'),
(5, 12, 1370933037, 'in');
SELECT * FROM latest_io;
SQL Fiddle で実際に動作しているのを見るにはここをクリックしてください。
このクエリを試してください。
select id,user, max(time), io
FROM lms_attendance group by user;
OK
SELECT id, MAX(user) as user, MAX(time) as time, MAX(io) as io FROM lms_attendance GROUP BY id;
select b.* from
(select
`lms_attendance`.`user` AS `user`,
max(`lms_attendance`.`time`) AS `time`
from `lms_attendance`
group by
`lms_attendance`.`user`) a
join
(select *
from `lms_attendance` ) b
on a.user = b.user
and a.time = b.time
select result from (
select vorsteuerid as result, count(*) as anzahl from kreditorenrechnung where kundeid = 7148
group by vorsteuerid
) a order by anzahl desc limit 0,1