এসকিউএল ওভার () ধারা - কখন এবং কেন এটি কার্যকর?


169
    USE AdventureWorks2008R2;
GO
SELECT SalesOrderID, ProductID, OrderQty
    ,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
    ,AVG(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Avg'
    ,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Count'
    ,MIN(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Min'
    ,MAX(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Max'
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);

আমি এই ধারাটি পড়েছি এবং আমার কেন এটি প্রয়োজন তা আমি বুঝতে পারি না। ফাংশনটি কী করে Over? কি করে Partitioning By? কেন আমি লেখার সাথে একটি প্রশ্ন করতে পারি না Group By SalesOrderID?


30
আপনি আরডিবিএমএস কী ব্যবহার করেন তা বিবেচনা না করেই পোস্টগ্রিস টিউটোরিয়ালটি সহায়ক হতে পারে। উদাহরণ আছে; আমাকে সাহায্য করে ছিল.
অ্যান্ড্রু লাজার

উত্তর:


144

আপনি ব্যবহার করতে পারেন GROUP BY SalesOrderID। পার্থক্যটি হ'ল GROUP BY এর সাথে আপনার কাছে কেবল গ্রোপ বাইয়ের অন্তর্ভুক্ত নয় কলামগুলির জন্য একত্রিত মান থাকতে পারে।

বিপরীতে, GROUP BY এর পরিবর্তে উইন্ডোড সমষ্টি ফাংশনগুলি ব্যবহার করে, আপনি একত্রিত এবং অ-সংগৃহীত মান উভয়ই পুনরুদ্ধার করতে পারেন। এটি হ'ল যদিও আপনি নিজের উদাহরণের ক্যোয়ারিতে এটি করছেন না, আপনি একই মানদণ্ডগুলির মধ্যে পৃথক OrderQtyমান এবং তাদের পরিমাণ, গুন, গড় ইত্যাদি উভয়ই পেতে পারেন SalesOrderID

এখানে উইন্ডোড সমষ্টিগুলি দুর্দান্ত কেনার একটি ব্যবহারিক উদাহরণ। মনে করুন আপনার মোট মূল্যের শতাংশের কত শতাংশ তা গণনা করতে হবে। উইন্ডোড সমষ্টিগুলি ছাড়াই আপনাকে প্রথমে সম্মিলিত মানগুলির একটি তালিকা তৈরি করতে হবে এবং তারপরে এটি আবার মূল রোসেটটিতে যোগ দিতে হবে, যেমন:

SELECT
  orig.[Partition],
  orig.Value,
  orig.Value * 100.0 / agg.TotalValue AS ValuePercent
FROM OriginalRowset orig
  INNER JOIN (
    SELECT
      [Partition],
      SUM(Value) AS TotalValue
    FROM OriginalRowset
    GROUP BY [Partition]
  ) agg ON orig.[Partition] = agg.[Partition]

এখন দেখুন আপনি কীভাবে উইন্ডোড সমষ্টি সহ এটি করতে পারেন:

SELECT
  [Partition],
  Value,
  Value * 100.0 / SUM(Value) OVER (PARTITION BY [Partition]) AS ValuePercent
FROM OriginalRowset orig

অনেক সহজ এবং ক্লিনার, তাই না?


68

OVERদফা শক্তিশালী আপনি বিভিন্ন রেঞ্জ ( "windowing") উপর দলা থাকতে পারে কিনা আপনি একটি ব্যবহার GROUP BYবা না

উদাহরণ: প্রতিটি হিসাবে SalesOrderIDগণনা এবং গণনা পান

SELECT
    SalesOrderID, ProductID, OrderQty
    ,COUNT(OrderQty) AS 'Count'
    ,COUNT(*) OVER () AS 'CountAll'
FROM Sales.SalesOrderDetail 
WHERE
     SalesOrderID IN(43659,43664)
GROUP BY
     SalesOrderID, ProductID, OrderQty

বিভিন্ন COUNTএস, নাGROUP BY

SELECT
    SalesOrderID, ProductID, OrderQty
    ,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'CountQtyPerOrder'
    ,COUNT(OrderQty) OVER(PARTITION BY ProductID) AS 'CountQtyPerProduct',
    ,COUNT(*) OVER () AS 'CountAllAgain'
FROM Sales.SalesOrderDetail 
WHERE
     SalesOrderID IN(43659,43664)

47

আপনি যদি কেবল বিক্রয়অর্ডারআইডি দ্বারা গ্রুপ করতে চেয়েছিলেন তবে আপনি পণ্য বিভাগ এবং অর্ডারক্টি কলামগুলি নির্বাচন বিভাগে অন্তর্ভুক্ত করতে পারবেন না।

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

SELECT
    O.order_id,
    O.order_date,
    ROW_NUMBER() OVER(PARTITION BY O.order_id) AS line_item_no,
    OL.product_id
FROM
    Orders O
INNER JOIN Order_Lines OL ON OL.order_id = O.order_id

(আমার বাক্য গঠনটি কিছুটা বন্ধ হতে পারে)

তারপরে আপনি এমন কিছু ফিরে পাবেন:

order_id    order_date    line_item_no    product_id
--------    ----------    ------------    ----------
    1       2011-05-02         1              5
    1       2011-05-02         2              4
    1       2011-05-02         3              7
    2       2011-05-12         1              8
    2       2011-05-12         2              1

42

আমাকে একটি উদাহরণ দিয়ে ব্যাখ্যা করতে দিন এবং আপনি এটি কীভাবে কাজ করে তা দেখতে সক্ষম হবেন।

ধরে নিচ্ছি আপনার নিম্নোক্ত টেবিল DIM_EQUIPMENT রয়েছে:

VIN         MAKE    MODEL   YEAR    COLOR
-----------------------------------------
1234ASDF    Ford    Taurus  2008    White
1234JKLM    Chevy   Truck   2005    Green
5678ASDF    Ford    Mustang 2008    Yellow

এসকিউএল এর নীচে চালান

SELECT VIN,
  MAKE,
  MODEL,
  YEAR,
  COLOR ,
  COUNT(*) OVER (PARTITION BY YEAR) AS COUNT2
FROM DIM_EQUIPMENT

ফলাফল নীচের হিসাবে হবে

VIN         MAKE    MODEL   YEAR    COLOR     COUNT2
 ----------------------------------------------  
1234JKLM    Chevy   Truck   2005    Green     1
5678ASDF    Ford    Mustang 2008    Yellow    2
1234ASDF    Ford    Taurus  2008    White     2

কি হয়েছে দেখুন।

আপনি গ্রুপ বাই অন ইয়ার ইয়ার এবং ম্যাচটি ROW এর সাথে মিলতে পারবেন।

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

 WITH EQ AS
  ( SELECT YEAR AS YEAR2, COUNT(*) AS COUNT2 FROM DIM_EQUIPMENT GROUP BY YEAR
  )
SELECT VIN,
  MAKE,
  MODEL,
  YEAR,
  COLOR,
  COUNT2
FROM DIM_EQUIPMENT,
  EQ
WHERE EQ.YEAR2=DIM_EQUIPMENT.YEAR;

17

ওভার ক্লজটি পার্টিশন বাই পার্টিশনের সাথে একত্রিত হওয়ার পরে বলা হয়েছে যে পূর্ববর্তী ফাংশন কলটি কোয়েরির ফিরে আসা সারিগুলির মূল্যায়ন করে বিশ্লেষণাত্মকভাবে করতে হবে। এটিকে একটি ইনলাইন গ্রুপ বাই স্টেটমেন্ট হিসাবে ভাবেন।

OVER (PARTITION BY SalesOrderID) উল্লেখ করছে যে এসইউএম, এভিজি ইত্যাদির জন্য ... ফাংশনটির জন্য, ক্যোয়ারী থেকে ফেরত রেকর্ডগুলির একটি উপসেটের ওভারে মান এবং বিদেশী কী বিক্রয়অর্ডারাইডের সাহায্যে অংশটি ভাগ করে।

সুতরাং আমরা প্রতিটি অনন্য বিক্রয় অর্ডারআইডির জন্য প্রতিটি অর্ডারক্টি রেকর্ড সুম করব এবং সেই কলামটির নামটি 'মোট' বলা হবে।

একই তথ্য সন্ধানের জন্য একাধিক ইনলাইন ভিউ ব্যবহার করার চেয়ে এটি অনেক বেশি কার্যকর উপায়। আপনি এই ক্যোয়ারীটিকে একটি ইনলাইন ভিউয়ের মধ্যে রাখতে পারেন এবং মোটে ফিল্টার করতে পারেন।

SELECT ...,
FROM (your query) inlineview
WHERE Total < 200

2
  • ক্লজও বলা হয় Query Petition
  • Group Byদফার মতোই

    • খণ্ডগুলিতে তথ্য বিভক্ত করুন (বা পার্টিশন)
    • বিভাজন সীমা দ্বারা পৃথক
    • ফাংশন পার্টিশনের মধ্যে সঞ্চালিত হয়
    • বিভাজন সীমানা অতিক্রম করার সময় পুনরায় সূচনা

সিনট্যাক্স:
ফাংশন (...) ওভার (কোল 1 কল 3, ... দ্বারা পার্টিশন)

  • ক্রিয়াকলাপ

    • পরিচিত ফাংশন যেমন COUNT(), SUM(), MIN(), MAX(), ইত্যাদি
    • পাশাপাশি নতুন নতুন কার্যাবলী (যেমন ROW_NUMBER(), RATION_TO_REOIRT()ইত্যাদি)


উদাহরণ সহ আরও তথ্য: http://msdn.microsoft.com/en-us/library/ms189461.aspx


-3
prkey   whatsthat               cash   
890    "abb                "   32  32
43     "abbz               "   2   34
4      "bttu               "   1   35
45     "gasstuff           "   2   37
545    "gasz               "   5   42
80009  "hoo                "   9   51
2321   "ibm                "   1   52
998    "krk                "   2   54
42     "kx-5010            "   2   56
32     "lto                "   4   60
543    "mp                 "   5   65
465    "multipower         "   2   67
455    "O.N.               "   1   68
7887   "prem               "   7   75
434    "puma               "   3   78
23     "retractble         "   3   81
242    "Trujillo's stuff   "   4   85

এটি ক্যোয়ারির ফলাফল। উত্স হিসাবে ব্যবহৃত সারণি একই প্রসারিত যে এর কোনও শেষ কলাম নেই। এই কলামটি তৃতীয়টির চলমান যোগফল।

প্রশ্ন:

SELECT prkey,whatsthat,cash,SUM(cash) over (order by whatsthat)
    FROM public.iuk order by whatsthat,prkey
    ;

(টেবিলটি সর্বজনীন হিসাবে যায়)

sql version:  2012

এটি ডিবেস (1986) স্তর থেকে কিছুটা ওভার, জানি না কেন এটি শেষ করতে 25+ বছর প্রয়োজন হয়েছিল।

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