2012-10-05 17 views
6

द्वारा MySQL समूह मैंने यहां समान प्रकार के प्रश्न देखा लेकिन उनमें से कोई भी मेरी स्थिति में मदद नहीं करता।आईडी और नवीनतम डेटाटाइम

मैं एक मेज कहना टेस्ट (mysql MyISAM का प्रयोग करके)

टेस्ट निम्न स्कीमा है की सुविधा देता है है:

TID INT PRIMARY KEY AUTO_INCREMENT 
    TData varchar (data that i want to select) 
    TUserID INT (this will be joined with users table, same users can have many records here) 
    TViewedAt DATETIME (records each time user visits page, datetime format) 

अब हर बार एक परीक्षण पृष्ठ वर्तमान में उपयोगकर्ता के प्रवेश का दौरा किया है, यह रिकॉर्ड कहते हैं इस तालिका में उपयोगकर्ता आईडी को रिकॉर्ड करने वाले किसी भी व्यक्ति को रिकॉर्ड करने के लिए, कुछ डेटा और तिथि और समय जो उपयोगकर्ता टीआईडी ​​के साथ जाते थे, हर बार स्वतः बढ़ते थे।

फिर मेरे पास बैकएंड प्रबंधित पृष्ठ है जहां मैं देख सकता हूं कि कौन सा उपयोगकर्ता परीक्षण पृष्ठ पर गया, कितनी बार, डेटा और कब। असल में यह 20-25 नवीनतम पंक्तियों की सूची वाला एक टेबल है। मेरी क्वेरी केवल प्रति डेटा एक रिकॉर्ड का चयन करना चाहिए। डेटा उपयोगकर्ता के लिए अलग-अलग समय पर समान हो सकता है लेकिन मैं केवल प्रत्येक उपयोगकर्ता के लिए एक डेटा चुनना चाहता हूं जो सबसे नवीनतम है। तो यदि उपयोगकर्ता 10 बार परीक्षण पृष्ठ पर जाता है, तो 10 रिकॉर्ड डेटाबेस पर जाते हैं लेकिन तालिका पर केवल 1 नवीनतम रिकॉर्ड प्रदर्शित करते हैं। यदि कोई अन्य उपयोगकर्ता 15 बार पृष्ठ पर जाता है तो यह इस दूसरे उपयोगकर्ता के लिए 1 रिकॉर्ड प्रदर्शित करता है जो कि नवीनतम है, इसलिए अब कुल मिलाकर हमारे पास तालिका में 2 पंक्तियां प्रदर्शित होती हैं। मुझे सबकुछ काम करने के लिए मिला लेकिन किसी कारण से ग्रुप बाय और MAX (तारीख) मुझे प्रत्येक तारीख के लिए नवीनतम डेटाटाइम नहीं देता है।

SELECT * 
    FROM Test 
    WHERE TUserID = 123 
    GROUP BY TData 
    ORDER BY TViewedAt 

रिटर्न 2 पंक्तियाँ जिसमें से उन पंक्तियों में से कोई भी नवीनतम हैं:

यहाँ मेरी क्वेरी है।

धन्यवाद बहुत

उत्तर

11

मुझे लगता है कि नीचे के साथ आप जो चाहते हैं उसे प्राप्त कर सकते हैं, इन ऑपरेशन को "समूहवार अधिकतम" कहा जाता है।

विकल्प 1

यह सबसे आसान समझने के लिए, एक सबक्वेरी अधिकतम TID सभी उपयोगकर्ताओं के लिए max के बाद से वापस आ जाएगी Group By के साथ एक साथ इस्तेमाल किया जाता है और की तुलना में हम एक अन्य प्रश्न करना के लिए सभी डेटा प्राप्त करने के लिए वो आईडी

Select TID, TData, TUserID, TViewedAt 
From Test 
Where TID In(
    Select Max(TID) 
    From Test 
    Group By TUserID 
) 

विकल्प 2

थोड़ा और अधिक जटिल को समझने के लिए है, लेकिन सबसे अधिक संभावना अधिक कुशल, इस आधार पर काम करता है जब t1.TViewedAt इसकी अधिकतम मूल्य पर है, वहाँ है कि एक अधिक से अधिक मूल्य के साथ कोई t2.TViewedAt और टी 2 पंक्ति मान NULL होगा।

SELECT t1.TID, t1.TData, t1.TUserID, t1.TViewedAt 
FROM Test t1 
LEFT JOIN Test t2 ON t1.TUserID = t2.TUserID AND t1.TViewedAt < t2.TViewedAt 
WHERE t2.TUserID IS NULL; 

परिणाम

TID TData TUserID TViewedAt 
4 test3 123  2012-10-05 00:00:00.000 
5 test2 213  2012-10-03 00:00:00.000 
+0

हाँ यह काम कर रहा है, बहुत बहुत धन्यवाद, बहुत आसान और आसान – Giorgi

+0

आपका स्वागत है, –

+1

मदद करने में खुशी है ऐसा करने का कोई तरीका है यह अधिक कुशल है, यानी, सबक्वायरीज़ की आवश्यकता नहीं है? मुझे लगता है कि यह मेरे सर्वर को मार रहा है – Jason

1

आप अधिकतम कुल के लिए GROUP BY TUserID की जरूरत है।

SELECT 
    TID, 
    TData, 
    main.TUserID 
    main.TViewedAt 
FROM 
    yourTable main 
    JOIN ( 
    SELECT TUserID, MAX(TViewedAt) AS TViewedAT FROM yourTable GROUP BY TUserID 
) tmax ON main.TUserID = tmax.TUserID AND main.TViewedAt = tmax.TViewedAt 

यह एक पोर्टेबल विधि है जो एक सबक्वायरी के खिलाफ जुड़ती है। उपकुंजी नवीनतम उपयोगकर्ता को TUserID,TViewedAt प्रति उपयोगकर्ता खींचती है, और यह मेल खाने वाले TData खींचने के लिए मुख्य तालिका के विरुद्ध वापस आ गई है।

आप केवल एक समय में एक उपयोगकर्ता चाहते हैं, आप कर सकते हैं:

SELECT 
    TData, 
    TViewedAt 
FROM yourTable 
WHERE TUserID = 'someid' 
GROUP BY TUserId 
HAVING TViewedAt = MAX(TViewedAt) 

ऊपर एक ही रास्ता मैं इसे हालांकि लिखा है MySQL में काम करेंगे। अन्य आरडीबीएमएस इस तथ्य के बारे में शिकायत करेंगे कि TDataSELECT सूची में दिखाई देता है लेकिन GROUP BY में नहीं है।

+0

दूसरा एक मैं करने की कोशिश की मदद और 0 पंक्तियों लौटे सकता है। TViewed क्या DATETIME प्रारूप MAX को समझता है? – Giorgi

+1

@Giorgi MAX() डेटाटाइम कॉलम को समझता है। पहले व्यक्ति का उपयोग करें, लेकिन इच्छित उपयोगकर्ता को सीमित करने के लिए WHERE क्लॉज जोड़ें। पहला दो का बेहतर और अधिक पोर्टेबल है। –

0
SELECT t1.TData, t1.TUserID, t1.TViewedAt 
FROM Test t1 
JOIN 
(SELECT TUserID, MAX(TViewedAt) 
FROM Test 
GROUP BY TUserID) t2 
ON t1.TUserID = t2.TUserID AND t1.TViewedAt=t2.TViewedAt 
+0

जो काम नहीं करता :( – Giorgi

+0

क्षमा करें, याद आया कि टीडीटा अलग हो सकता है। फिर अपडेट देखें ... – alex

1
क्वेरी के बाद

, हैं-

select * from pages where date(create_date)=(select date(create_date) from pages order by create_date limit 1) 
+1

क्या आप समझा सकते हैं कि यह प्रश्न का उत्तर कैसे देता है? – Braiam

संबंधित मुद्दे