Giả sử tôi có một trò chơi có thể chơi bởi 2, 3 hoặc 4 người chơi. Tôi theo dõi một trò chơi như vậy trong cơ sở dữ liệu của tôi (MySQL 5.1) trong ba bảng, được đưa ra dưới đây. Tôi hy vọng rằng các lĩnh vực là tự giải thích:Còn lại cùng một bàn nhiều lần
create table users (id int, login char(8));
create table games (id int, stime datetime, etime datetime);
create table users_games (uid int, gid int, score int);
[Hai lần được theo dõi trong bảng trò chơi được bắt đầu và kết thúc thời gian]
Dưới đây là một số dữ liệu giả để cư trú trong bảng:
insert into games values
(1, '2011-12-01 10:00:00', '2011-12-01 13:00:00'),
(2, '2011-12-02 11:00:00', '2011-12-01 14:00:00'),
(3, '2011-12-03 12:00:00', '2011-12-01 15:00:00'),
(4, '2011-12-04 13:00:00', '2011-12-01 16:00:00');
insert into users_games values
(101, 1, 10),
(102, 1, 11),
(101, 2, 12),
(103, 2, 13),
(104, 2, 14),
(102, 3, 15),
(103, 3, 16),
(104, 3, 17),
(105, 3, 18),
(102, 4, 19),
(104, 4, 20),
(105, 4, 21);
Bây giờ, tôi cần phải tạo ra một báo cáo theo định dạng sau:
gid p1 p2 p3 p4 started ended
1 101 102 [g1] [g1]
2 101 103 104 [g2] [g2]
3 102 103 104 105 [g3] [g3]
4 102 104 105 [g4] [g4]
Đó là, một báo cáo hiển thị tất cả những người chơi đã chơi trò chơi trong cùng một hàng. Tôi cũng cần điểm số của họ và một số thông tin khác từ bảng người dùng, nhưng đó là giai đoạn 2. :-)
tôi bắt đầu với điều này:
select g.id, g.stime, g.etime, ug1.uid, ug2.uid, ug3.uid, ug4.uid
from games g, users_games ug1, users_games ug2, users_games ug3, users_games ug4
where
g.id = ug1.gid and
ug1.gid = ug2.gid and
ug1.uid < ug2.uid and
ug2.gid = ug3.gid and
ug2.uid < ug3.uid and
ug3.gid = ug4.gid and
ug3.uid < ug4.uid
này mang lại cho tôi tất cả các trò chơi mà tất cả bốn chỗ ngồi đã bị chiếm đóng (nghĩa là chỉ có ID trò chơi 3 trong dữ liệu giả ở trên). Nhưng đó chỉ là một tập con của dữ liệu tôi cần.
Đây là nỗ lực thứ hai của tôi:
select g.id, g.stime, g.etime, ug1.uid, ug2.uid,
ifnull(ug3.uid, ''), ifnull(ug4.uid, '')
from (games g, users_games ug1, users_games ug2)
left join users_games ug3 on ug2.gid = ug3.gid and ug2.uid < ug3.uid
left join users_games ug4 on ug3.gid = ug4.gid and ug3.uid < ug4.uid
where
g.id = ug1.gid and
ug1.gid = ug2.gid and
ug1.uid < ug2.uid
này mang lại cho tôi 14 hàng với dữ liệu giả trên. Tôi cố gắng để loại bỏ một nguồn lỗi bằng cách neo ug1 đến việc giao cho các cầu thủ thấp nhất-UID:
select g.id, g.stime, g.etime, ug1.uid, ug2.uid,
ifnull(ug3.uid, ''), ifnull(ug4.uid, '')
from
(games g, users_games ug1, users_games ug2,
(select gid as g, min(uid) as u from users_games group by g) as xx
)
left join users_games ug3 on ug2.gid = ug3.gid and ug2.uid < ug3.uid
left join users_games ug4 on ug3.gid = ug4.gid and ug3.uid < ug4.uid
where
g.id = xx.g and
ug1.uid = xx.u and
g.id = ug1.gid and
ug1.gid = ug2.gid and
ug1.uid < ug2.uid
Bây giờ tôi xuống đến 9 dòng, nhưng tôi vẫn còn có rất nhiều dữ liệu giả mạo. Tôi có thể thấy vấn đề - ví dụ trong trò chơi 3, với ug1 được neo vào người dùng 102, vẫn có ba người chơi mà ug2 có thể được neo. Và cứ thế. Nhưng tôi không thể tìm ra cách để giải quyết câu hỏi hóc búa này - làm thế nào để cuối cùng tôi có thể đạt được một truy vấn sẽ xuất ra 4 hàng với người chơi theo đúng thứ tự và số?
Điều này dường như với tôi phải là vấn đề được giải quyết trong các ngữ cảnh khác. Sẽ đánh giá cao tất cả sự giúp đỡ ở đây.
tôi khuyên bạn * không * trộn cú pháp ',' và 'JOIN'. Chỉ cần sử dụng 'JOIN', nó không phải là 20 năm lỗi thời ... – MatBailie