2009-08-16 33 views
6

Các bạn, tôi có truy vấn về cơ bản chọn trình duyệt mới nhất mà người dùng của chúng tôi đã sử dụng.Chọn một từ trên cùng từ bên ngoài bên trái tham gia

ở đây là chúng tôi (giản thể) Bảng cấu trúc

HITS_TABLE 
---------- 
USERID 
BROWSER 
HITSDATE 

USER_TABLE 
---------- 
USERID 
USERNAME 

và đây là cách tôi truy vấn các trình duyệt mới nhất mà người dùng của chúng tôi sử dụng

SELECT U.*, H.BROWSER 

FROM USER_TABLE U 

CROSS APPLY 
    (SELECT TOP 1 BROWSER 
    FROM HITS_TABLE 
    WHERE HITS_TABLE.USERID = U.USERID 
    ORDER BY HITS_TABLE.HITSDATE DESC 
)as H 

Các HITS_TABLE chỉ được thêm vài ngày trước.

Vì vậy, truy vấn đó chỉ là kết quả mà người dùng đã truy cập trang web của chúng tôi sau khi chúng tôi đã thêm HITS_TABLE và loại bỏ những người khác.

Đây là trường hợp mẫu

USER_TABLE 
------------------- 
USERID  USERNAME 
------------------- 
1   'Spolski' 
2   'Atwoord 
3   'Dixon' 


HITS_TABLE 
------------------------------ 
USERID  HITSDATE  BROWSER 
------------------------------ 
2   15/8/2009 'Firefox 3.5' 
1   16/8/2009 'IE 6' 
2   16/8/2009 'Chrome' 

Đây là kết quả mẫu

------------------------------ 
USERID  USERNAME  BROWSER 
------------------------------ 
1   'Spolsky' 'IE 6' 
2   'Atwoord' 'Chrome' 

Nhưng, tôi muốn thêm người dùng khác với trình duyệt 'vô danh'. Đây là kết quả mong muốn của tôi

------------------------------ 
USERID  USERNAME  BROWSER 
------------------------------ 
1   'Spolsky' 'IE 6' 
2   'Atwoord' 'Chrome' 
3   'Dixon'  'Unknown' 

Tôi tin rằng nó có thể đạt được bằng LEFT OUTER JOIN. Nhưng tôi luôn luôn có điều này: (Tôi KHÔNG muốn kết quả này)

------------------------------ 
USERID  USERNAME  BROWSER 
------------------------------ 
1   'Spolsky' 'IE 6' 
2   'Atwoord' 'Chrome' 
2   'Atwoord' 'Firefox 3.5' 
3   'Dixon'  'Unknown' 

Tôi hy vọng câu hỏi của tôi là rõ ràng.

Trả lời

6

sử dụng một nhóm bởi trên userid so với hits_table cho phép bạn để có được những hitsdate max() cho mỗi userid. Tôi đã gọi HITS MỚI NHẤT này trong mã bên dưới.

Chọn trên USER TABLE với phép nối trái với LATEST HITS cho phép bạn kéo bản ghi cho mọi người dùng.

tham gia trở lại vào HITS TABLE, sau đó allwos bạn kéo bản ghi trình duyệt được liên kết với ngày đó, hoặc một null cho người dùng không có bản ghi trong đó.

select 
    user_table.userid, 
    user_table.username, 
    isnull(hitstable.browser, 'unknown') as browser 
from 
    user_table 
left join 
(
    select 
    userid, 
    max(hitsdate) hitsdate 
    from 
    hits_table 
    group by 
    userid 
) latest_hits 
on 
    user_table.userid = latest_hits.userid  
left join 
    hits_table 
on hits.table.userid = latest_hits.userid 
and hits_table.hitsdate = latest_hits.hitsdate 
+2

Giải pháp này cần có một thực tế quan trọng cần lưu ý là các giải pháp khác bị thiếu: Điều gì sẽ xảy ra nếu kết hợp USERID và HITSDATE không rõ ràng, ví dụ: một hàng bổ sung (2, 16/8/2009, 'Safari') tồn tại? Sử dụng các hàm xếp hạng bạn sẽ nhận được một kết quả không xác định. Bạn có thể cho biết cái nào được chọn? Giải pháp này sẽ cung cấp cho cả hai cominations IMHO tốt hơn nhiều. –

+0

Thông tin bổ sung: Để biết thông tin về Xếp hạng SQL Server, hãy xem http://msdn.microsoft.com/en-us/library/ms189798%28SQL.90%29.aspx –

+0

bạn nói đúng. Hàm max() rất hữu ích cho việc này. cảm ơn bạn. nhưng tôi nghĩ rằng nó nên được bên ngoài tham gia. –

3

Không thể bạn phụ select, không đẹp, nhưng nên làm việc ..

SELECT U.*, 

ISNULL((SELECT TOP 1 BROWSER 
    FROM HITS_TABLE 
    WHERE HITS_TABLE.USERID = U.USERID 
    ORDER BY HITS_TABLE.HITSDATE DESC),'UnKnown') AS Browser 

FROM USER_TABLE U 
+1

Nếu bạn muốn truy cập bất kỳ cột nào khác ngoài trình duyệt từ bảng truy cập trong truy vấn này thì lựa chọn phụ không dành cho bạn. Trong trường hợp đó tôi sẽ hồ sơ các giải pháp @rwarren và @gbn để xem giải pháp nào hoạt động tốt hơn. @Mao có một điểm thú vị về kết quả không xác định. Với chiếc mũ thực dụng của bạn, bạn có thể bỏ qua trường hợp cạnh này bằng cách thêm Thời gian cho bạn HITSDATE. –

0
SELECT U.*,'BROWSER' = 
    case 
    when (SELECT TOP 1 BROWSER FROM HITS_TABLE WHERE HITS_TABLE.USERID = U.USERID ORDER BY HITS_TABLE.HITSDATE DESC) is null then 'Unknown' 
else (SELECT TOP 1 BROWSER FROM HITS_TABLE WHERE HITS_TABLE.USERID = U.USERID ORDER BY HITS_TABLE.HITSDATE DESC) 
    end 
FROM USER_TABLE U 
+0

Trong giải pháp của bạn sẽ không chọn phụ thực hiện hai lần khi kết quả không phải là null? Thứ nhất để đánh giá "khi nào" và tìm ra trình duyệt không phải là null và thứ hai trong "else" để trích xuất kết quả? –

Các vấn đề liên quan