একটি নির্বাচন বিবৃতিতে "পূর্ববর্তী সারি" মান অ্যাক্সেস করার কোন উপায় আছে?


96

আমাকে একটি টেবিলের দুটি লাইনের মধ্যে একটি কলামের পার্থক্য গণনা করতে হবে। এসকিউএল-তে সরাসরি এটি করার কোনও উপায় আছে কি? আমি মাইক্রোসফ্ট এসকিউএল সার্ভার 2008 ব্যবহার করছি।

আমি এই জাতীয় কিছু খুঁজছি:

SELECT value - (previous.value) FROM table

"পূর্ববর্তী" চলকটি সর্বশেষ নির্বাচিত সারিটি উল্লেখ করে। অবশ্যই এর মতো একটি নির্বাচনের সাথে আমি এন-সারিগুলির সাথে একটি টেবিলটিতে নির্বাচিত এন -1 সারি দিয়ে শেষ করব, এটি সম্ভবত না, আসলে আমার প্রয়োজনটি ঠিক তাই।

এটা কি কোনওভাবে সম্ভব?


6
ঠিক এখন নতুন দর্শকদের জন্য দরকারী একটি মন্তব্য যুক্ত করা। এসকিউএল ২০১২ এ এখনই ল্যাগ এবং নেতৃত্ব দিয়েছে
কেডি

উত্তর:


65

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

select t1.value - t2.value from table t1, table t2 
where t1.primaryKey = t2.primaryKey - 1

যদি আপনি জানেন যে কীভাবে জিনিসগুলি অর্ডার করতে হয় তবে কীভাবে বর্তমান মান হিসাবে দেওয়া হয় (EG, আপনি বর্ণানুক্রমিক অর্ডার করতে চান) তবে আমি স্ট্যান্ডার্ড এসকিউএল এ করার কোনও উপায় জানি না, তবে বেশিরভাগ এসকিউএল বাস্তবায়ন হবে এটি করতে এক্সটেনশনগুলি।

এসকিউএল সার্ভারের জন্য এখানে একটি উপায় রয়েছে যা আপনি যদি সারিগুলিকে এমনভাবে অর্ডার করতে পারেন যে প্রত্যেকে স্বতন্ত্র:

select  rank() OVER (ORDER BY id) as 'Rank', value into temp1 from t

select t1.value - t2.value from temp1 t1, temp1 t2 
where t1.Rank = t2.Rank - 1

drop table temp1

যদি আপনার সম্পর্কগুলি ভাঙার দরকার হয় তবে আপনি অর্ডার দিয়ে প্রয়োজনীয় যতগুলি কলাম যুক্ত করতে পারেন।


এটি ঠিক আছে, অর্ডার কোনও সমস্যা নয়, আমি এটিকে আরও সহজ করার জন্য উদাহরণ থেকে সরিয়েছি, আমি এটি চেষ্টা করব।
এডউইন জার্ভিস

7
যা ধরে নিয়েছে যে প্রাথমিক কীগুলি ক্রমানুসারে উত্পন্ন হয় এবং সারিগুলি কখনই মুছে ফেলা হয় না এবং নির্বাচনের কোনও অন্য অর্ডার ক্লজ থাকে না এবং এবং ...
মার্টিনস্টটনার

মার্টিন ঠিক আছে। যদিও এটি কিছু ক্ষেত্রে কার্যকর হতে পারে আপনার উত্সাহিত আইডির উপর নির্ভর না করেই ব্যবসায়ের দিক থেকে আপনার "পূর্ববর্তী" দ্বারা ঠিক কী বোঝানো উচিত তা আপনাকে সত্যই নির্ধারণ করতে হবে।
টম এইচ

আপনি ঠিক বলেছেন, আমি একটি এসকিউএল সার্ভার এক্সটেনশন ব্যবহার করে একটি উন্নতি যুক্ত করেছি।
রসফ্যাব্রিক্যান্ট

4
"এটি ঠিক আছে, অর্ডার কোনও সমস্যা নয়" এর জবাবে ... ... তবে আপনি কেন আপনার ক্যোয়ারীতে একটি সালিসি মান বাদ দিবেন না কেননা আপনি যদি অর্ডার বিবেচনা না করেন তবে আপনি এটি করছেন কেন?
জনএফএক্স

85

ল্যাগ ফাংশনটি ব্যবহার করুন :

SELECT value - lag(value) OVER (ORDER BY Id) FROM table

আইডির জন্য ব্যবহৃত সিকোয়েন্সগুলি মানগুলি এড়িয়ে যেতে পারে, তাই আইডি -1 সর্বদা কাজ করে না।


4
এটি PostgreSQL সমাধান। প্রশ্নটি এমএসএসকিউএল সম্পর্কে। এমএস স্কুয়েল সংস্করণ এ ধরনের ফাংশন আছে 2012+ ( msdn.microsoft.com/en-us/en-en/library/hh231256(v=sql.120).aspx )
Kromster

10
@ ক্রমস্টারন কেবল পোস্টগ্র্যাসএসকিউএল সমাধান নয়। এসকিউএল উইন্ডো ফাংশনগুলি এসকিউএল: 2003 স্ট্যান্ডার্ডে প্রবর্তিত হয়েছিল ।
হান্স জিনজেল

ল্যাগ ফাংশন তিন পরামিতি নিতে পারেন: LAG(ExpressionToSelect, NumberOfRowsToLag, DefaultValue)। পিছিয়ে যাওয়ার জন্য সারির ডিফল্ট সংখ্যা 1, তবে আপনি যখন সেটটির শুরুতে পিছিয়ে থাকা সম্ভব না হয় তখন আপনি এটি এবং ডিফল্ট মান নির্বাচন করতে পারেন।
ভেন্ডিল

30

ওরাকল, পোস্টগ্র্যাসকিউএল, এসকিউএল সার্ভার এবং আরও অনেকগুলি আরডিবিএমএস ইঞ্জিন বিশ্লেষণমূলক ফাংশন রয়েছে LAGএবং LEADএটি খুব কাজ করে।

এসকিউএল সার্ভারে 2012 এর আগে আপনাকে নিম্নলিখিতগুলি করতে হবে:

SELECT  value - (
        SELECT  TOP 1 value
        FROM    mytable m2
        WHERE   m2.col1 < m1.col1 OR (m2.col1 = m1.col1 AND m2.pk < m1.pk)
        ORDER BY 
                col1, pk
        )
FROM mytable m1
ORDER BY
      col1, pk

, COL1আপনি যে কলামটি অর্ডার করছেন তা কোথায় ।

ইনডেক্স থাকা (COL1, PK)এই কোয়েরিকে ব্যাপকভাবে উন্নত করবে।


14
এসকিউএল সার্ভার ২০১২-তে এখন ল্যাগ এবং নেতৃত্বও রয়েছে।
এরিক

হানা এসকিউএল স্ক্রিপ্টটি ল্যাগ এবং নেতৃত্বকে সমর্থন করে।
মিক

মাতৃশক্তিতে এটি করার জন্য সন্ধান করতে এখানে উপস্থিত দর্শকদের কাছে কেবল একটি মন্তব্য যুক্ত করতে। এটিতে ল্যাগ এবং এলএডি ফাংশন রয়েছে। ডকুমেন্টেশন এখানে: cwiki.apache.org/confluence/display/Hive/…
ক্যাফারেল

27
WITH CTE AS (
  SELECT
    rownum = ROW_NUMBER() OVER (ORDER BY columns_to_order_by),
    value
  FROM table
)
SELECT
  curr.value - prev.value
FROM CTE cur
INNER JOIN CTE prev on prev.rownum = cur.rownum - 1

কোয়েরিতে কোনও গ্রুপিং না থাকলে এটি সঠিকভাবে কাজ করে, তবে আমরা যদি কেবলমাত্র একটি গ্রুপের মধ্যে পূর্ববর্তী মান থেকে মানগুলি বিয়োগ করতে চাই, একই কর্মচারী বলতে পারি, তবে আমরা কীভাবে এটি করতে পারি? কোজ এটি চালাচ্ছে কেবলমাত্র প্রতিটি গ্রুপের শীর্ষ 2 সারিগুলির জন্য এবং that গোষ্ঠীর বাকী সারিগুলির জন্য নয়। এর জন্য, আমি লুপের সময় এই কোডটি চালাচ্ছিলাম তবে এটি খুব ধীর বলে মনে হচ্ছে। আমরা এই দৃশ্যে অন্য কোন পদ্ধতির হতে পারে? এবং এটি খুব কেবল এসকিউএল সার্ভারে 2008?
হেমন্ত সিসোদিয়া

10

বামটি টেবিলটিকে নিজের সাথে যোগ দিন, যোগদানের শর্তটি কাজ করে যাতে সারণীর জোড়িত সংস্করণে সারিটি মিলিত হয় তবে আপনার "পূর্ববর্তী" এর নির্দিষ্ট সংজ্ঞা রয়েছে definition

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


হালনাগাদ:

এসকিএল সার্ভারের নতুন সংস্করণগুলিতেও ল্যাগ এবং লিড উইন্ডোয়িং ফাংশন রয়েছে যা এর জন্যও ব্যবহার করা যেতে পারে।



2

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

আপনার ফাঁক থাকলে এই পদ্ধতিটি কাজ করা উচিত

declare @temp (value int, primaryKey int, tempid int identity)
insert value, primarykey from mytable order by  primarykey

select t1.value - t2.value from @temp  t1
join @temp  t2 
on t1.tempid = t2.tempid - 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.