আমি প্রতিটি কী মানের জন্য সাম্প্রতিক টাইমস্ট্যাম্প সহ সারিগুলি কীভাবে নির্বাচন করতে পারি?


88

আমি সেন্সর ডেটা একটি টেবিল আছে। প্রতিটি সারিতে সেন্সর আইডি, একটি টাইমস্ট্যাম্প এবং অন্যান্য ক্ষেত্র রয়েছে। আমি অন্যান্য কিছু ক্ষেত্র সহ প্রতিটি সেন্সরের জন্য সর্বশেষ টাইমস্ট্যাম্প সহ একটি একক সারি নির্বাচন করতে চাই।

আমি ভেবেছিলাম যে সমাধানটি সেন্সর আইডি দ্বারা গোষ্ঠী করা হবে এবং তারপরে সর্বোচ্চ (টাইমস্ট্যাম্প) এর মাধ্যমে আদেশ করুন:

SELECT sensorID,timestamp,sensorField1,sensorField2 
FROM sensorTable 
GROUP BY sensorID 
ORDER BY max(timestamp);

এটি আমাকে এই বলে একটি ত্রুটি দেয় যে "সেন্সরফিল্ড 1 অবশ্যই দলে দলে গ্রুপে উপস্থিত হওয়া উচিত বা সামগ্রিকভাবে ব্যবহার করা উচিত।"

এই সমস্যার কাছে যাওয়ার সঠিক উপায় কী?


4
আপনি কোন ডিবি ইঞ্জিন ব্যবহার করছেন?
জুয়ারজেন d

4
যদিও সর্বাধিক (টাইমস্ট্যাম্প) মান JOIN ব্যবহার করে নীচের উত্তরগুলি কাজ করা উচিত, আমি সেন্সররেটেডে যদি আপনার কোনও উত্তর থাকে তবে আমি একটি সেন্সররেডিং আইডিতে যোগদানের পরামর্শ দেব।
থমাস ল্যাংস্টন

উত্তর:


94

সম্পূর্ণতার জন্য, এখানে আরও একটি সম্ভাব্য সমাধান রয়েছে:

SELECT sensorID,timestamp,sensorField1,sensorField2 
FROM sensorTable s1
WHERE timestamp = (SELECT MAX(timestamp) FROM sensorTable s2 WHERE s1.sensorID = s2.sensorID)
ORDER BY sensorID, timestamp;

সুন্দর স্ব-ব্যাখ্যা আমি মনে করি, কিন্তু এখানে আরও তথ্য আপনি চাইলে, পাশাপাশি অন্যান্য উদাহরণ। এটি মাইএসকিউএল ম্যানুয়াল থেকে এসেছে, তবে উপরের ক্যোয়ারী প্রতিটি আরডিবিএমএসের সাথে কাজ করে (sql'92 মান বাস্তবায়ন করে)।


57

এটি SELECT DISTINCTনিম্নলিখিত হিসাবে তুলনামূলকভাবে মার্জিত উপায়ে সম্পন্ন করতে পারেন :

SELECT DISTINCT ON (sensorID)
sensorID, timestamp, sensorField1, sensorField2 
FROM sensorTable
ORDER BY sensorID, timestamp DESC;

উপরের পোস্টগ্র্রেএসকিউএল এর জন্য কাজ করে ( এখানে আরও কিছু তথ্য ) তবে আমি অন্যান্য ইঞ্জিনগুলিও মনে করি। যদি এটি সুস্পষ্ট না হয় তবে এটি সেন্সর আইডি এবং টাইমস্ট্যাম্প অনুসারে সারণিটিকে সাজিয়ে তোলে (সবচেয়ে প্রাচীন থেকে প্রাচীন) এবং তারপরে প্রতিটি অনন্য সংবেদক আইডির জন্য প্রথম সারিতে (অর্থাত্ সর্বশেষ টাইমস্ট্যাম্প) প্রদান করে।

আমার ব্যবহারের ক্ষেত্রে আমার ~ 1 কে সেন্সর থেকে 10M রিডিং রয়েছে, তাই টাইমস্ট্যাম্প-ভিত্তিক ফিল্টারটিতে নিজের সাথে টেবিলে যোগদানের চেষ্টা করা খুব উত্স-নিবিড়; উপরেরটি কয়েক সেকেন্ড সময় নেয়।


এই সমাধানটি আসলেই দ্রুত।
এনা

দ্রুত এবং বুঝতে সহজ। ব্যবহারের ক্ষেত্রেও ব্যাখ্যা করার জন্য ধন্যবাদ, যেমন খনিটিও বেশ অনুরূপ।
স্টিপ ভারডোনক

4
দুর্ভাগ্যক্রমে, এটি মাইএসকিউএল ( লিঙ্ক ) এর জন্য কাজ করে না
সাইলেন্টসুরফার

21

আপনি নিজের সাথে টেবিলটিতে যোগ দিতে পারেন (সেন্সর আইডিতে), এবং left.timestamp < right.timestampযোগদানের শর্ত হিসাবে যোগ করতে পারেন। তারপরে আপনি সারিগুলি বাছাই করুন, কোথায় right.idআছেন null। ভয়েলা, আপনি সেন্সর প্রতি সর্বশেষ এন্ট্রি পেয়েছেন।

http://sqlfiddle.com/#!9/45147/37

SELECT L.* FROM sensorTable L
LEFT JOIN sensorTable R ON
L.sensorID = R.sensorID AND
L.timestamp < R.timestamp
WHERE isnull (R.sensorID)

তবে দয়া করে নোট করুন, আপনার যদি অল্প পরিমাণে আইডিস এবং অনেক মান থাকে তবে এটি খুব সংস্থানীয় সংস্থান হবে! সুতরাং, আমি এটি কোনও ধরণের পরিমাপ-স্টাফের জন্য সুপারিশ করব না, যেখানে প্রতিটি সেন্সর প্রতি মিনিটে একটি মান সংগ্রহ করে। তবে ব্যবহার-ক্ষেত্রে, যেখানে আপনাকে "কখনও কখনও" পরিবর্তিত এমন কোনও "রিভিশনস" ট্র্যাক করতে হবে, এটি সহজেই চলছে।


এটি অন্যান্য উত্তরের চেয়ে দ্রুত, কমপক্ষে আমার ক্ষেত্রে।
বৃষ্টি_

@rain_ এটি সত্যিই ব্যবহারের ক্ষেত্রে নির্ভর করে। সুতরাং, এই প্রশ্নের কোনও "সার্বজনীন উত্তর" নেই।
ডোগান করুন

19

আপনি কেবল গোষ্ঠীতে থাকা বা একটি সামগ্রিক ফাংশনে ব্যবহৃত কলামগুলি নির্বাচন করতে পারেন। আপনি এই কাজ পেতে একটি যোগদান ব্যবহার করতে পারেন

select s1.* 
from sensorTable s1
inner join 
(
  SELECT sensorID, max(timestamp) as mts
  FROM sensorTable 
  GROUP BY sensorID 
) s2 on s2.sensorID = s1.sensorID and s1.timestamp = s2.mts

... বা select * from sensorTable where (sensorID, timestamp) in (select sensorID, max(timestamp) from sensorTable group by sensorID)
আরজান

আমি মনে করি "বাম জয়েন্ট" পাশাপাশি প্রয়োগ করা হয়, কেবল "অভ্যন্তরীণ যোগদান" নয়; এবং একটি অংশ "এবং এস 1.টাইমস্ট্যাম্প = s2.mts" নেসেসারি আইএমএইচও নয়। এবং তবুও, আমি দুটি ক্ষেত্রের সূচক তৈরি করার পরামর্শ দিচ্ছি: সেন্সরআইডি + টাইমস্ট্যাম্প - ক্যোয়ারের গতি দুর্দান্ত বৃদ্ধি করে!
ইগোর

4
WITH SensorTimes As (
   SELECT sensorID, MAX(timestamp) "LastReading"
   FROM sensorTable
   GROUP BY sensorID
)
SELECT s.sensorID,s.timestamp,s.sensorField1,s.sensorField2 
FROM sensorTable s
INNER JOIN SensorTimes t on s.sensorID = t.sensorID and s.timestamp = t.LastReading

2

এখানে একটি সাধারণ উত্তর আমি এখনও দেখতে পাইনি, এটি উইন্ডো ফাংশন। এটি আপনার সম্পর্কিত ডাব্লু সমর্থন করে, তাহলে এটি সহ সম্পর্কিত সাব-কোয়েরির বিকল্প।

SELECT sensorID,timestamp,sensorField1,sensorField2 
FROM (
    SELECT sensorID,timestamp,sensorField1,sensorField2
        , ROW_NUMBER() OVER(
            PARTITION BY sensorID
            ORDER BY timestamp
        ) AS rn
    FROM sensorTable s1
WHERE rn = 1
ORDER BY sensorID, timestamp;

আমি পারস্পরিক সম্পর্কযুক্ত সাব-কোয়েরির চেয়ে আকস্মিকভাবে এটি ব্যবহার করি। বোধগম্যতার বিষয়ে মন্তব্যগুলিতে বিনা দ্বিধায় আমাকে দ্বিধাদ্বন্দ্ব জানায়, এটি সম্পর্কে এটি কীভাবে সজ্জিত তা আমি নিশ্চিত নই।


0

আমার বেশিরভাগ ক্ষেত্রে একই সমস্যা ছিল এবং এএএর বিভিন্ন সমাধান শেষ হয়ে গেছে যা এই ধরণের সমস্যাটিকে কোয়েরি করতে নগণ্য করে তোলে।

আমার সেন্সর ডেটার একটি টেবিল রয়েছে (প্রায় 30 সেন্সর থেকে 1 মিনিটের ডেটা)

SensorReadings->(timestamp,value,idSensor)

এবং আমার একটি সেন্সর টেবিল রয়েছে যাতে সেন্সর সম্পর্কে প্রচুর স্ট্যাটিক স্টাফ থাকে তবে সংশ্লিষ্ট ক্ষেত্রগুলি হ'ল:

Sensors->(idSensor,Description,tvLastUpdate,tvLastValue,...)

সেন্সরআরডিংস টেবিলে সন্নিবেশগুলিতে একটি ট্রিগার হিসাবে টিভিলাস্টআপডেট এবং টিভিলাস্টভ্যালু সেট করা আছে। আমার কাছে কোনও মূল্যবান অনুসন্ধানের প্রয়োজন ছাড়াই সবসময় এই মানগুলিতে সরাসরি অ্যাক্সেস থাকে। এটি কিছুটা অস্বীকৃতি জানায়। প্রশ্নটি তুচ্ছ:

SELECT idSensor,Description,tvLastUpdate,tvLastValue 
FROM Sensors

আমি প্রায়শই জিজ্ঞাসা করা তথ্যের জন্য এই পদ্ধতিটি ব্যবহার করি। আমার ক্ষেত্রে আমার কাছে একটি সেন্সর টেবিল এবং একটি বড় ইভেন্টের টেবিল রয়েছে, যার মিনিটের পর্যায়ে ডেটা আসে এবং কয়েক ডজন মেশিন সেই ডেটা দিয়ে ড্যাশবোর্ড এবং গ্রাফ আপডেট করে। আমার ডেটা দৃশ্যের সাথে ট্রিগার এবং ক্যাশে পদ্ধতিটি ভালভাবে কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.