প্রথম শব্দ
আপনি JOIN গুলি নীচে (এবং সহ) বিভাগগুলি নিরাপদে উপেক্ষা করতে পারেন: আপনি কেবল কোডটির ক্র্যাক নিতে চাইলে শুরু শুরু if পটভূমি এবং ফলাফল মাত্র প্রসঙ্গ হিসাবে পরিবেশন করা। আপনি যদি প্রাথমিকভাবে কোডটি দেখতে কেমন দেখতে চান তবে দয়া করে 2015-10-06 এর আগে সম্পাদনা ইতিহাস দেখুন।
উদ্দেশ্য
শেষ পর্যন্ত আমি টেবিলের মধ্যে উপলব্ধ জিপিএস ডেটার ডেটটাইম স্ট্যাম্পগুলির উপর ভিত্তি করে ট্রান্সমিটারের ( X
বা Xmit
) ইন্টারপোলটেড জিপিএস স্থানাঙ্কগুলি গণনা করতে চাই যা টেবিলে SecondTable
পর্যবেক্ষণটিকে সরাসরি ফ্ল্যাঙ্ক করে FirstTable
।
চূড়ান্ত উদ্দেশ্য অর্জনের জন্য আমার তাত্ক্ষণিক উদ্দেশ্য হ'ল সেই স্বল্প সময় পয়েন্টগুলি পেতে কীভাবে সেরা যোগদান FirstTable
করা যায় SecondTable
তা নির্ধারণ করা। পরবর্তীতে আমি সেই তথ্যটি ব্যবহার করতে পারি মধ্যবর্তী জিপিএস স্থানাংকগুলি গণনা করতে পারি সমুদ্রের সমন্বয় ব্যবস্থা বরাবর রৈখিক ফিটিং ধরে রেখেছি (অভিনব শব্দ বলতে আমি এই বিষয়টিকে বিবেচনা করি না যে পৃথিবী এই স্কেলটিতে একটি গোলক)।
প্রশ্নাবলি
- টাইম স্ট্যাম্পগুলির আগে-পরে-নিকটস্থ সবচেয়ে বেশি কার্যকর উপায় আছে কি?
- কেবল "পরে" দখল করে এবং তারপরে "পরে" সম্পর্কিত হিসাবে কেবল "আগে" পেয়ে আমার দ্বারা স্থির।
- আরও একটি স্বজ্ঞাত উপায় আছে যা
(A<>B OR A=B)
কাঠামোর সাথে জড়িত নয় ।- বায়ার্ডজি মৌলিক বিকল্পগুলি সরবরাহ করেছিলেন, তবে আমার "রিয়েল-ওয়ার্ল্ড" অভিজ্ঞতা তার 4 টি যোগদানের কৌশলগুলি একইভাবে সম্পাদন করে না। তবে বিকল্প যোগদানের শৈলীগুলিকে সম্বোধনের জন্য তার সম্পূর্ণ কৃতিত্ব।
- আপনার কাছে থাকতে পারে অন্য কোনও চিন্তা, কৌশল এবং পরামর্শ।
- উভয় Thusfar byrdzeye এবং Phrancis এ ব্যাপারে বেশ সহায়ক হয়েছে। আমি দেখতে পেলাম যে ফ্রেঞ্চিসের পরামর্শটি চমৎকারভাবে নির্ধারণ করা হয়েছিল এবং একটি জটিল পর্যায়ে সহায়তা সরবরাহ করেছিল, তাই আমি তাকে এখানে প্রান্তটি দেব।
প্রশ্ন 3 সম্পর্কে আমি যে কোনও অতিরিক্ত সহায়তা পেতে পারি তার জন্য আমি তার কৃতজ্ঞতা প্রকাশ করব Bul
সারণী সংজ্ঞা
আধা ভিজ্যুয়াল উপস্থাপনা
FirstTable
Fields
RecTStamp | DateTime --can contain milliseconds via VBA code (see Ref 1)
ReceivID | LONG
XmitID | TEXT(25)
Keys and Indices
PK_DT | Primary, Unique, No Null, Compound
XmitID | ASC
RecTStamp | ASC
ReceivID | ASC
UK_DRX | Unique, No Null, Compound
RecTStamp | ASC
ReceivID | ASC
XmitID | ASC
SecondTable
Fields
X_ID | LONG AUTONUMBER -- seeded after main table has been created and already sorted on the primary key
XTStamp | DateTime --will not contain partial seconds
Latitude | Double --these are in decimal degrees, not degrees/minutes/seconds
Longitude | Double --this way straight decimal math can be performed
Keys and Indices
PK_D | Primary, Unique, No Null, Simple
XTStamp | ASC
UIDX_ID | Unique, No Null, Simple
X_ID | ASC
রিসিভারডেটেলস টেবিল
Fields
ReceivID | LONG
Receiver_Location_Description | TEXT -- NULL OK
Beginning | DateTime --no partial seconds
Ending | DateTime --no partial seconds
Lat | DOUBLE
Lon | DOUBLE
Keys and Indicies
PK_RID | Primary, Unique, No Null, Simple
ReceivID | ASC
ValidXmitters সারণী
Field (and primary key)
XmitID | TEXT(25) -- primary, unique, no null, simple
এসকিউএল ফিডাল ...
... যাতে আপনি সারণী সংজ্ঞা এবং কোড দিয়ে খেলতে পারেন এই প্রশ্নটি এমএসএ্যাকসেসের জন্য, তবে ফ্রেঞ্চিস যেমন উল্লেখ করেছেন, অ্যাক্সেসের জন্য কোনও এসকিউএল ফ্রেডল স্টাইল নেই। সুতরাং, ফ্রেঞ্চিসের উত্তরের উপর ভিত্তি করে আমার সারণী সংজ্ঞা এবং কোড দেখতে আপনি এখানে যেতে সক্ষম হবেন : http://sqlfiddle.com/#!6/e9942/4 (বাহ্যিক লিঙ্ক)
যোগ দিন: শুরু হচ্ছে
আমার বর্তমান "অভ্যন্তরীণ সাহস" জয়েন কৌশল
প্রথমে কলাম অর্ডার এবং যৌগিক প্রাথমিক কী (RecTStamp, ReceivID, XmitID)
সমস্ত সূচকযুক্ত / সাজানো হয়েছে এমন একটি ফার্স্ট টেবিল_প্রযুক্তি তৈরি করুন ASC
। আমি পৃথকভাবে প্রতিটি কলামে সূচি তৈরি করেছি। তারপরে এটি পূরণ করুন।
INSERT INTO FirstTable_rekeyed (RecTStamp, ReceivID, XmitID)
SELECT DISTINCT ROW RecTStamp, ReceivID, XmitID
FROM FirstTable
WHERE XmitID IN (SELECT XmitID from ValidXmitters)
ORDER BY RecTStamp, ReceivID, XmitID;
উপরের জিজ্ঞাসাটি 153006 রেকর্ড সহ নতুন টেবিলটি পূরণ করে এবং 10 সেকেন্ড বা তার বেশি সময়ের মধ্যে ফিরে আসে।
নিম্নলিখিত 1 বা দুটি মধ্যে সম্পূর্ণ করা হয় যখন শীর্ষ 1 সাবকোরি পদ্ধতিটি ব্যবহৃত হয় যখন এই পুরো পদ্ধতিটি একটি "নির্বাচন গণনা (*) ফর্ম (...)" এ আবৃত থাকে
SELECT
ReceiverRecord.RecTStamp,
ReceiverRecord.ReceivID,
ReceiverRecord.XmitID,
(SELECT TOP 1 XmitGPS.X_ID FROM SecondTable as XmitGPS WHERE ReceiverRecord.RecTStamp < XmitGPS.XTStamp ORDER BY XmitGPS.X_ID) AS AfterXmit_ID
FROM FirstTable_rekeyed AS ReceiverRecord
-- INNER JOIN SecondTable AS XmitGPS ON (ReceiverRecord.RecTStamp < XmitGPS.XTStamp)
GROUP BY RecTStamp, ReceivID, XmitID;
-- No separate join needed for the Top 1 method, but it would be required for the other methods.
-- Additionally no restriction of the returned set is needed if I create the _rekeyed table.
-- May not need GROUP BY either. Could try ORDER BY.
-- The three AfterXmit_ID alternatives below take longer than 3 minutes to complete (or do not ever complete).
-- FIRST(XmitGPS.X_ID)
-- MIN(XmitGPS.X_ID)
-- MIN(SWITCH(XmitGPS.XTStamp > ReceiverRecord.RecTStamp, XmitGPS.X_ID, Null))
পূর্ববর্তী "অভ্যন্তর সাহস" JOIN ক্যোয়ারী
প্রথম (ফাস্টিশ ... তবে যথেষ্ট ভাল নয়)
SELECT
A.RecTStamp,
A.ReceivID,
A.XmitID,
MAX(IIF(B.XTStamp<= A.RecTStamp,B.XTStamp,Null)) as BeforeXTStamp,
MIN(IIF(B.XTStamp > A.RecTStamp,B.XTStamp,Null)) as AfterXTStamp
FROM FirstTable as A
INNER JOIN SecondTable as B ON
(A.RecTStamp<>B.XTStamp OR A.RecTStamp=B.XTStamp)
GROUP BY A.RecTStamp, A.ReceivID, A.XmitID
-- alternative for BeforeXTStamp MAX(-(B.XTStamp<=A.RecTStamp)*B.XTStamp)
-- alternatives for AfterXTStamp (see "Aside" note below)
-- 1.0/(MAX(1.0/(-(B.XTStamp>A.RecTStamp)*B.XTStamp)))
-- -1.0/(MIN(1.0/((B.XTStamp>A.RecTStamp)*B.XTStamp)))
দ্বিতীয় (ধীর)
SELECT
A.RecTStamp, AbyB1.XTStamp AS BeforeXTStamp, AbyB2.XTStamp AS AfterXTStamp
FROM (FirstTable AS A INNER JOIN
(select top 1 B1.XTStamp, A1.RecTStamp
from SecondTable as B1, FirstTable as A1
where B1.XTStamp<=A1.RecTStamp
order by B1.XTStamp DESC) AS AbyB1 --MAX (time points before)
ON A.RecTStamp = AbyB1.RecTStamp) INNER JOIN
(select top 1 B2.XTStamp, A2.RecTStamp
from SecondTable as B2, FirstTable as A2
where B2.XTStamp>A2.RecTStamp
order by B2.XTStamp ASC) AS AbyB2 --MIN (time points after)
ON A.RecTStamp = AbyB2.RecTStamp;
পটভূমি
আমার কাছে একটি DateTime
স্ট্যাম্প, ট্রান্সমিটার আইডি এবং রেকর্ডিং ডিভাইস আইডির উপর ভিত্তি করে একটি যৌগিক প্রাথমিক কী সহ 1 মিলিয়ন এর নিচে একটি টেলিমেট্রি টেবিল (এ হিসাবে এলিয়াসযুক্ত) রয়েছে । আমার নিয়ন্ত্রণের বাইরে অবস্থার কারণে, আমার এসকিউএল ভাষা হ'ল মাইক্রোসফ্ট অ্যাক্সেসের স্ট্যান্ডার্ড জেট ডিবি (ব্যবহারকারীরা 2007 এবং পরবর্তী সংস্করণগুলি ব্যবহার করবেন)। এই এন্ট্রিগুলির মধ্যে প্রায় 200,000 ট্রান্সমিটার আইডির কারণে ক্যোয়ারীর সাথে প্রাসঙ্গিক।
একটি দ্বিতীয় টেলিমেট্রি টেবিল রয়েছে (ওরফে বি) যার মধ্যে একটি একক সহ প্রায় 50,000 এন্ট্রি জড়িত DateTime
প্রাথমিক কী
প্রথম পদক্ষেপের জন্য, আমি দ্বিতীয় টেবিল থেকে প্রথম টেবিলের স্ট্যাম্পগুলির নিকটতম টাইমস্ট্যাম্পগুলি সন্ধান করার দিকে মনোনিবেশ করেছি।
যোগদান ফলাফল
যে আবিষ্কারগুলি আমি আবিষ্কার করেছি ...
... ডিবাগিংয়ের সময় পথে
এটি JOIN
যুক্তিটি লিখলে সত্যই অদ্ভুত লাগে FROM FirstTable as A INNER JOIN SecondTable as B ON (A.RecTStamp<>B.XTStamp OR A.RecTStamp=B.XTStamp)
যেহেতু @ বার্ডজেয়ে একটি মন্তব্যে উল্লেখ করেছেন (যেহেতু অদৃশ্য হয়ে গেছে) ক্রস- জয়েনের একটি রূপ। লক্ষ্য করুন বদলে LEFT OUTER JOIN
জন্য INNER JOIN
প্রদর্শিত হয় উপরে কোডে পরিমাণ বা লাইন ফিরে পরিচয় কোন প্রভাব তৈরি করতে হবে। আমিও অন ক্লজটি ছেড়ে দিতে বা বলতে পারি না ON (1=1)
। (A <> B বা A = B) স্পষ্টরূপে প্রত্যাবর্তন হিসাবে সারণিতে A সারণীতে কেবলমাত্র একটি লাইন পরিবর্তে সারিগুলির পরিবর্তে ( INNER
বা এর চেয়ে LEFT OUTER
JOIN
) পরিবর্তনের জন্য কমা ব্যবহার করে Count(select * from A) * Count(select * from B)
এই ক্যোয়ারিতে JOIN
ফিরে এসেছে। এটি স্পষ্টভাবে উপযুক্ত নয়। FIRST
কোনও যৌগিক প্রাথমিক কী ধরণের দেওয়া ব্যবহারের জন্য উপলব্ধ বলে মনে হচ্ছে না।
দ্বিতীয় JOIN
শৈলী, যদিও যুক্তিযুক্তভাবে আরও সুস্পষ্ট, তত ধীরে ধীরে ভুগছে। এটি হতে পারে কারণ JOIN
বৃহত টেবিলের বিপরীতে CROSS JOIN
উভয় বিকল্পে পাওয়া দুটি অতিরিক্ত অভ্যন্তর প্রয়োজন ।
অন্যদিকে: IIF
ধারাটির সাথে প্রতিস্থাপন MIN
/ MAX
একই সংখ্যক এন্ট্রি ফিরিয়ে দেয়।
MAX(-(B.XTStamp<=A.RecTStamp)*B.XTStamp)
"পূর্বে" ( MAX
) টাইমস্ট্যাম্পের জন্য কাজ করে, তবে নিম্নলিখিত "পরে" ( MIN
) এর জন্য সরাসরি কাজ করে না :
MIN(-(B.XTStamp>A.RecTStamp)*B.XTStamp)
কারণ সর্বনিম্ন সর্বদা FALSE
শর্তের জন্য 0 হয় । এই 0 কোনও পূর্ব -যুগের চেয়ে কম DOUBLE
(কোন DateTime
ক্ষেত্রটি অ্যাক্সেসের একটি উপসেট এবং এই গণনাটি ক্ষেত্রটিকে রূপান্তর করে)। IIF
এবং MIN
/ MAX
পদ্ধতি বিকল্পসমূহ শূন্য দ্বারা কারণ বিভাজন AfterXTStamp মান কাজের জন্য প্রস্তাবিত ( FALSE
) নাল মান, যা সমষ্টিগত ফাংশন MIN এবং MAX উপর লাফালাফি জেনারেট করে।
পরবর্তী পদক্ষেপ
এটিকে আরও এগিয়ে নিয়ে যাওয়ার জন্য, আমি দ্বিতীয় টেবিলের টাইমস্ট্যাম্পগুলি সন্ধান করতে চাই যা সরাসরি প্রথম টেবিলের টাইমস্ট্যাম্পগুলি সরাসরি ফ্ল্যাঙ্ক করে এবং those পয়েন্টগুলির সময় দূরত্বের উপর ভিত্তি করে দ্বিতীয় সারণী থেকে ডেটা মানগুলির একটি রৈখিক প্রবৃদ্ধি সম্পাদন করে (যেমন যদি টাইমস্ট্যাম্প থেকে প্রথম টেবিলটি "আগে" এবং "পরে" এর মধ্যে 25% পথ হিসাবে গণনা করা মানের 25% "" পরে "পয়েন্টের সাথে এবং" আগে "থেকে 75% এর সাথে যুক্ত দ্বিতীয় সারণির মান ডেটা থেকে আসা উচিত )। অভ্যন্তরীণ সাহসের অংশ হিসাবে সংশোধিত যোগদানের ধরণটি ব্যবহার করে, এবং নীচের প্রস্তাবিত উত্তরগুলির পরে আমি উত্পন্ন করি ...
SELECT
AvgGPS.XmitID,
StrDateIso8601Msec(AvgGPS.RecTStamp) AS RecTStamp_ms,
-- StrDateIso8601MSec is a VBA function returning a TEXT string in yyyy-mm-dd hh:nn:ss.lll format
AvgGPS.ReceivID,
RD.Receiver_Location_Description,
RD.Lat AS Receiver_Lat,
RD.Lon AS Receiver_Lon,
AvgGPS.Before_Lat * (1 - AvgGPS.AfterWeight) + AvgGPS.After_Lat * AvgGPS.AfterWeight AS Xmit_Lat,
AvgGPS.Before_Lon * (1 - AvgGPS.AfterWeight) + AvgGPS.After_Lon * AvgGPS.AfterWeight AS Xmit_Lon,
AvgGPS.RecTStamp AS RecTStamp_basic
FROM ( SELECT
AfterTimestampID.RecTStamp,
AfterTimestampID.XmitID,
AfterTimestampID.ReceivID,
GPSBefore.BeforeXTStamp,
GPSBefore.Latitude AS Before_Lat,
GPSBefore.Longitude AS Before_Lon,
GPSAfter.AfterXTStamp,
GPSAfter.Latitude AS After_Lat,
GPSAfter.Longitude AS After_Lon,
( (AfterTimestampID.RecTStamp - GPSBefore.XTStamp) / (GPSAfter.XTStamp - GPSBefore.XTStamp) ) AS AfterWeight
FROM (
(SELECT
ReceiverRecord.RecTStamp,
ReceiverRecord.ReceivID,
ReceiverRecord.XmitID,
(SELECT TOP 1 XmitGPS.X_ID FROM SecondTable as XmitGPS WHERE ReceiverRecord.RecTStamp < XmitGPS.XTStamp ORDER BY XmitGPS.X_ID) AS AfterXmit_ID
FROM FirstTable AS ReceiverRecord
-- WHERE ReceiverRecord.XmitID IN (select XmitID from ValidXmitters)
GROUP BY RecTStamp, ReceivID, XmitID
) AS AfterTimestampID INNER JOIN SecondTable AS GPSAfter ON AfterTimestampID.AfterXmit_ID = GPSAfter.X_ID
) INNER JOIN SecondTable AS GPSBefore ON AfterTimestampID.AfterXmit_ID = GPSBefore.X_ID + 1
) AS AvgGPS INNER JOIN ReceiverDetails AS RD ON (AvgGPS.ReceivID = RD.ReceivID) AND (AvgGPS.RecTStamp BETWEEN RD.Beginning AND RD.Ending)
ORDER BY AvgGPS.RecTStamp, AvgGPS.ReceivID;
... যা প্রত্যাশিত রেকর্ডের চূড়ান্ত সংখ্যায় (কমপক্ষে আনুমানিক) অনুসারে 152928 রেকর্ড দেয়। রান টাইম সম্ভবত আমার আই 7-4790, 16 জিবি র্যাম, এসএসডি নেই, উইন 8.1 প্রো সিস্টেমের 5-10 মিনিট।
রেফারেন্স 1: এমএস অ্যাক্সেস মিলিসেকেন্ড সময় মানগুলি পরিচালনা করতে পারে - সত্যই এবং তার সাথে উত্স ফাইল [08080011.txt]