SQL Row_Number () फ़ंक्शन जहाँ क्लॉज़ में है


90

मैंने पाया Row_Number()कि जहां क्लॉज में फ़ंक्शन के साथ एक प्रश्न का उत्तर दिया गया है । जब मैंने एक क्वेरी की कोशिश की, तो मुझे निम्नलिखित त्रुटि मिल रही थी:

"Msg 4108, लेवल 15, स्टेट 1, लाइन 1 विंडो किए गए फ़ंक्शन केवल क्लाज द्वारा SELECT या ORDER में दिखाई दे सकते हैं।"

यहाँ वह क्वेरी है जिसकी मैंने कोशिश की थी। अगर कोई इसे हल करना जानता है, तो कृपया मुझे बताएं।

SELECT employee_id 
FROM V_EMPLOYEE 
WHERE row_number() OVER ( ORDER BY employee_id ) > 0 
ORDER BY Employee_ID

9
ROW_NUMBER() OVER (ORDER BY employee_id) > 0हमेशा मूल्यांकन करेगाTRUE
क्वासोनी

3
हाँ, यह सही है। मैं उस स्थिति के बारे में चिंतित नहीं हूं, जिसे मैं किसी भी समय बदल सकता हूं। मैं चाहता हूं कि क्वेरी पहले काम करे, फिर 500 और 800 के बीच का रौद्र रूप रखने की सोच ... धन्यवाद

2
@ जोसेफ: आप सीटीई का उपयोग करने से बचने की कोशिश क्यों कर रहे हैं?
OMG पॉनीज़

1
@ ग्रिड - मैं SQL सर्वर का विशेषज्ञ नहीं हूं। मैं एक बड़ी परियोजना में एक टीम की मदद करने की कोशिश कर रहा हूं जहां वे प्रदर्शन के साथ बहुत सारे मुद्दों का सामना कर रहे हैं। वे यूडीएफ और सीटीई का उपयोग कर रहे हैं। तालिका में से एक में, उनके पास सिर्फ 5000 रिकॉर्ड हैं, और यदि 5 उपयोगकर्ता एक खोज तक पहुंचते हैं, तो इसे पुनर्प्राप्त करने में एक मिनट से अधिक समय लगता है। कुछ समय, यह विफल रहता है और समय समाप्त हो जाता है। इसलिए, मैं सीटीई और यूडीएफ से बचने की कोशिश कर रहा हूं और सीधे एसक्यूएल क्वेरी के साथ आने की कोशिश कर रहा हूं जो प्रदर्शन के मुद्दों को हल कर सकता है।

1
हाय सब, कृपया नीचे दिए गए लिंक को देखें जो एक अलग तरीके से row_number () का उपयोग करके उत्तर देता है। क्या कोई लिंक के साथ मेरी प्रारंभिक क्वेरी की तुलना कर सकता है? मदद की सराहना करें ..

जवाबों:


91

इस समस्या को हल करने के लिए, अपने चयनित कथन को CTE में लपेटें, और फिर आप CTE के खिलाफ क्वेरी कर सकते हैं और विंडो के फ़ंक्शन के परिणामों का उपयोग उस क्लॉज में कर सकते हैं।

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER ( order by employee_id )
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0

7
मैं सीटीई से बचने की कोशिश कर रहा हूं। मैं देख रहा हूँ बदतर मामला Thats। धन्यवाद

3
यदि आप CTE के बजाय सबक्वेरी का उपयोग करते हैं तो यह तेजी से चल सकता है। मैंने कुछ मामलों में 1.5 के कारक द्वारा बेहतर प्रदर्शन देखा है
ब्रायन वेबस्टर

3
CTE SELECT में भी TOP होना चाहिए अन्यथा SQL 2008 सर्वर ORDER BY के कारण क्वेरी को निष्पादित नहीं करेगा (जो कि असमर्थित है जब तक TOP का उपयोग नहीं किया जाता है)
Muflix

2
मैं SQL2005 (ugh) का उपयोग कर रहा हूं - मैं FROM के बाद "ORDER BY" को गिराकर "TOP" के उपयोग से बच सकता हूं। यह किसी भी तरह से (आदेश द्वारा) के साथ बेमानी है।
जो बी

मैं चाह रहा था कि सीटीई के बिना क्लॉज ROW_NUMBER()में उपयोग करने का एक तरीका है WHERE:(
जलाल

61
SELECT  employee_id
FROM    (
        SELECT  employee_id, ROW_NUMBER() OVER (ORDER BY employee_id) AS rn
        FROM    V_EMPLOYEE
        ) q
WHERE   rn > 0
ORDER BY
        Employee_ID

ध्यान दें कि यह फ़िल्टर निरर्थक है: से ROW_NUMBER()शुरू होता है 1और हमेशा से अधिक होता है 0


2
@ DavideChicco.it: SQL सर्वर में, व्युत्पन्न तालिकाओं के लिए एक उपनाम (मुझे AS qइसके बजाय लिखना चाहिए था , लेकिन यह या तो काम करेगा)।
क्वासोई 20

2
पठनीयता एक ध्यान मैं है जब उपनामों का नामकरण होता है। आप रोव्नर और क्यू के रूप में डिराइव्डटेबल के रूप में आरएन लिख सकते हैं और जहां क्लिअर के रूप में जहां डिराइवटेबल.राउंटरनंबर> 0. है। मेरी राय में यह 6 महीने के समय में बहुत कम भ्रामक होगा जब कोड आपके दिमाग में ताजा नहीं होगा।
एडवर्ड कोमू

2
@EdwardComeau: rnथोड़े इन दिनों पंक्ति संख्या के लिए सार्वभौमिक रूप से स्वीकार किए जाते हैं। Google खोज स्ट्रिंग में "row_number over ..." टाइप करने का प्रयास करें और देखें कि यह आपको क्या सुझाव देता है।
क्वासोइनी

3
@Quassnoi, पठनीयता अच्छी कोडिंग की कुंजी है और rn (या अन्य संक्षिप्त उपनाम) के अनुवाद के संज्ञानात्मक प्रयास अपने और अपने कोड को बनाए रखने वाले लोगों के लिए कहते हैं। NB, Microsoft ने सबसे पहले हिट किया, SEL ROW_NUMBER () OVER (ORDER BY SalesYTD DESC) AS Row, ... मैं भी rn भर में नहीं आया, इससे पहले कि "यूनिवर्सल" में आपका माइलेज अलग-अलग हो सकता है।
एडवर्ड कोमू

1
@Quassnoi, और दूसरी हिट, SO लेख - stackoverflow.com/questions/961007/how-do-i-use-row-number कई विविधताएँ और rn; ;-)
एडवर्ड कोमू

32
Select * from 
(
    Select ROW_NUMBER() OVER ( order by Id) as 'Row_Number', * 
    from tbl_Contact_Us
) as tbl
Where tbl.Row_Number = 5

19

मुझे लगता है कि आप कुछ इस तरह चाहते हैं:

SELECT employee_id 
FROM  (SELECT employee_id, row_number() 
       OVER (order by employee_id) AS 'rownumber' 
       FROM V_EMPLOYEE) TableExpressionsMustHaveAnAliasForDumbReasons
WHERE rownumber > 0

4
तालिका के लिए एक उपनाम बनाएं यदि उपरोक्त क्वेरी आपके लिए काम नहीं करती है। दूसरी अंतिम पंक्ति को संशोधित करें जैसे From V_EMPLOYEE) Aकि ए को उपनाम के रूप में जोड़ें।
हम्माद खान

7

एक इनलाइन दृश्य या CTE तेजी से होगा के संबंध में rexem के उत्तर पर टिप्पणियों के जवाब में, मैं एक तालिका I, और सभी का उपयोग करने के लिए प्रश्नों को फिर से प्राप्त करता हूं, उपलब्ध था: sys.objects।

WITH object_rows AS (
    SELECT object_id, 
        ROW_NUMBER() OVER ( ORDER BY object_id) RN
    FROM sys.objects)
SELECT object_id
FROM object_rows
WHERE RN > 1

SELECT object_id
FROM (SELECT object_id, 
        ROW_NUMBER() OVER ( ORDER BY object_id) RN
    FROM sys.objects) T
WHERE RN > 1

उत्पादित क्वेरी योजनाएं बिल्कुल वैसी ही थीं। मैं सभी मामलों में उम्मीद करूंगा, क्वेरी ऑप्टिमाइज़र एक ही योजना के साथ आएगा, कम से कम सीटीई के सरल प्रतिस्थापन में इनलाइन दृश्य या इसके विपरीत।

बेशक, यह देखने के लिए कि क्या अंतर है, अपने स्वयं के सिस्टम पर अपने स्वयं के प्रश्नों का प्रयास करें।

इसके अलावा, row_number()स्टैक ओवरफ्लो पर दिए गए उत्तरों में जहां क्लॉज एक सामान्य त्रुटि है। row_number()जब तक चयन खंड संसाधित नहीं किया जाता है तब तक तार्किकता उपलब्ध नहीं है। लोग यह भूल जाते हैं कि जब वे उत्तर का परीक्षण किए बिना उत्तर देते हैं, तो उत्तर कभी-कभी गलत होता है। (एक ऐसा आरोप जिसके लिए मैं स्वयं दोषी हूं।)


1
Thx शैनन। SQL सर्वर का आप किस संस्करण का उपयोग कर रहे थे?
OMG पोंजी

1
तो इसका मतलब है, उस लिंक में प्रदान किया गया उत्तर गलत है? लेकिन, सवाल पोस्ट करने वाला व्यक्ति इस बात से सहमत था कि इसका काम .. आश्चर्य की बात है .. :-)

2
@ जोसेफ, लेकिन यदि आप ओपी द्वारा पोस्ट किए गए एक अन्य प्रश्न को संबंधित प्रश्न में देखते हैं, तो आप देखेंगे कि वह कोड के एक संस्करण के लिए लिंक है जो स्वीकृत उत्तर में वैसा नहीं है। मुझे नहीं पता कि उसने जवाब क्यों स्वीकार किया, भले ही यह दर्ज नहीं किया गया था। शायद यह स्वीकार किए जाने के बाद किसी बिंदु पर संपादित किया गया था, शायद यह पूरी तरह से सही होने के बिना भी उसे पाने के लिए पर्याप्त था।
शैनन सेवरेंस

1
@Rexem: SQL Server 2005 और SQL Server 2008 दोनों। इससे पहले के संस्करण CTE या ROW_NUMBER () का समर्थन नहीं करते हैं
शैनन सेवरेंस

6

मुझे ऐसा लगता है कि CTE या सब क्वेरी का उपयोग करने वाले सभी उत्तर इसके लिए पर्याप्त सुधार हैं, लेकिन मैं किसी को भी दिल से नहीं देखता कि ओपी को कोई समस्या क्यों है। ओपी ने जो काम नहीं करने का कारण बताया है, वह तार्किक क्वेरी प्रोसेसिंग ऑर्डर के कारण है:

  1. से
  2. पर
  3. शामिल हों
  4. कहाँ पे
  5. समूह द्वारा
  6. CUBE / रोलअप के साथ
  7. होने
  8. चुनते हैं
  9. DISTINCT
  10. द्वारा आदेश
  11. ऊपर
  12. OFFSET / फ़ेच

मेरा मानना ​​है कि यह उत्तर में बहुत योगदान देता है, क्योंकि यह बताता है कि ऐसा क्यों होता है। कई कार्यों के लिए आवश्यक CTE या सब क्वेरी बनाने WHEREसे पहले हमेशा संसाधित किया जाता है SELECT। आपको SQL Server में यह बहुत कुछ दिखाई देगा।


4

CTE (SQL Server 2005+) का उपयोग करना:

WITH employee_rows AS (
  SELECT t.employee_id,
         ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
    FROM V_EMPLOYEE t)
SELECT er.employee_id
  FROM employee_rows er
 WHERE er.rownum > 1

इनलाइन दृश्य / गैर-सीटीई समतुल्य वैकल्पिक का उपयोग करना:

SELECT er.employee_id
  FROM (SELECT t.employee_id,
               ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
          FROM V_EMPLOYEE t) er
 WHERE er.rownum > 1

1
प्रदर्शन में कौन सा बेहतर है? CTE या सबक्वेरी का उपयोग करना? धन्यवाद

1
शैनन का जवाब देखें - उसके परीक्षण में वे बराबर हैं।
OMG पॉनीज

6
नहीं, यह तेज नहीं है। में SQL Server, CTEइनलाइन विचार समान हैं और उनका प्रदर्शन समान है। जब गैर-नियतात्मक कार्यों का उपयोग किया जाता है CTE, तो प्रत्येक कॉल पर इसका पुनर्मूल्यांकन किया जाता है। भौतिककरण को बल देने के लिए गंदे चालों का उपयोग करना पड़ता है CTE। मेरे ब्लॉग में इन लेखों को देखें: explainextended.com/2009/07/28/… explainextended.com/2009/05/28/generating-xml-in-subqueries
Quassnoi

2

ओपी के सवाल के जवाब पर आधारित:

कृपया इस लिंक को देखें। इसका एक अलग समाधान है, जो उस व्यक्ति के लिए काम करता है जिसने प्रश्न पूछा था। मैं इस तरह से एक समाधान निकालने की कोशिश कर रहा हूँ।

SQL Server 2005 में ROW_NUMBER () OVER () का उपयोग करके विभिन्न स्तंभों पर छँटाई का उपयोग करके पृष्ठांकित क्वेरी

~ यूसुफ

"विधि 1" लिंक किए गए प्रश्न से ओपी की क्वेरी की तरह है, और "विधि 2" चयनित उत्तर से क्वेरी की तरह है। आपको इस उत्तर में लिंक किए गए कोड को देखना होगा कि वास्तव में क्या चल रहा था, क्योंकि चयनित उत्तर में कोड को काम करने के लिए संशोधित किया गया था। इसे इस्तेमाल करे:

DECLARE @YourTable table (RowID int not null primary key identity, Value1 int, Value2 int, value3 int)
SET NOCOUNT ON
INSERT INTO @YourTable VALUES (1,1,1)
INSERT INTO @YourTable VALUES (1,1,2)
INSERT INTO @YourTable VALUES (1,1,3)
INSERT INTO @YourTable VALUES (1,2,1)
INSERT INTO @YourTable VALUES (1,2,2)
INSERT INTO @YourTable VALUES (1,2,3)
INSERT INTO @YourTable VALUES (1,3,1)
INSERT INTO @YourTable VALUES (1,3,2)
INSERT INTO @YourTable VALUES (1,3,3)
INSERT INTO @YourTable VALUES (2,1,1)
INSERT INTO @YourTable VALUES (2,1,2)
INSERT INTO @YourTable VALUES (2,1,3)
INSERT INTO @YourTable VALUES (2,2,1)
INSERT INTO @YourTable VALUES (2,2,2)
INSERT INTO @YourTable VALUES (2,2,3)
INSERT INTO @YourTable VALUES (2,3,1)
INSERT INTO @YourTable VALUES (2,3,2)
INSERT INTO @YourTable VALUES (2,3,3)
INSERT INTO @YourTable VALUES (3,1,1)
INSERT INTO @YourTable VALUES (3,1,2)
INSERT INTO @YourTable VALUES (3,1,3)
INSERT INTO @YourTable VALUES (3,2,1)
INSERT INTO @YourTable VALUES (3,2,2)
INSERT INTO @YourTable VALUES (3,2,3)
INSERT INTO @YourTable VALUES (3,3,1)
INSERT INTO @YourTable VALUES (3,3,2)
INSERT INTO @YourTable VALUES (3,3,3)
SET NOCOUNT OFF

DECLARE @PageNumber     int
DECLARE @PageSize       int
DECLARE @SortBy         int

SET @PageNumber=3
SET @PageSize=5
SET @SortBy=1


--SELECT * FROM @YourTable

--Method 1
;WITH PaginatedYourTable AS (
SELECT
    RowID,Value1,Value2,Value3
        ,CASE @SortBy
             WHEN  1 THEN ROW_NUMBER() OVER (ORDER BY Value1 ASC)
             WHEN  2 THEN ROW_NUMBER() OVER (ORDER BY Value2 ASC)
             WHEN  3 THEN ROW_NUMBER() OVER (ORDER BY Value3 ASC)
             WHEN -1 THEN ROW_NUMBER() OVER (ORDER BY Value1 DESC)
             WHEN -2 THEN ROW_NUMBER() OVER (ORDER BY Value2 DESC)
             WHEN -3 THEN ROW_NUMBER() OVER (ORDER BY Value3 DESC)
         END AS RowNumber
    FROM @YourTable
    --WHERE
)
SELECT
    RowID,Value1,Value2,Value3,RowNumber
        ,@PageNumber AS PageNumber, @PageSize AS PageSize, @SortBy AS SortBy
    FROM PaginatedYourTable
    WHERE RowNumber>=(@PageNumber-1)*@PageSize AND RowNumber<=(@PageNumber*@PageSize)-1
    ORDER BY RowNumber



--------------------------------------------
--Method 2
;WITH PaginatedYourTable AS (
SELECT
    RowID,Value1,Value2,Value3
        ,ROW_NUMBER() OVER
         (
             ORDER BY
                 CASE @SortBy
                     WHEN  1 THEN Value1
                     WHEN  2 THEN Value2
                     WHEN  3 THEN Value3
                 END ASC
                ,CASE @SortBy
                     WHEN -1 THEN Value1
                     WHEN -2 THEN Value2
                     WHEN -3 THEN Value3
                 END DESC
         ) RowNumber
    FROM @YourTable
    --WHERE  more conditions here
)
SELECT
    RowID,Value1,Value2,Value3,RowNumber
        ,@PageNumber AS PageNumber, @PageSize AS PageSize, @SortBy AS SortBy
    FROM PaginatedYourTable
    WHERE 
        RowNumber>=(@PageNumber-1)*@PageSize AND RowNumber<=(@PageNumber*@PageSize)-1
        --AND more conditions here
    ORDER BY
        CASE @SortBy
            WHEN  1 THEN Value1
            WHEN  2 THEN Value2
            WHEN  3 THEN Value3
        END ASC
       ,CASE @SortBy
            WHEN -1 THEN Value1
            WHEN -2 THEN Value2
            WHEN -3 THEN Value3
        END DESC

उत्पादन:

RowID  Value1 Value2 Value3 RowNumber  PageNumber  PageSize    SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10     2      1      1      10         3           5           1
11     2      1      2      11         3           5           1
12     2      1      3      12         3           5           1
13     2      2      1      13         3           5           1
14     2      2      2      14         3           5           1

(5 row(s) affected

RowID  Value1 Value2 Value3 RowNumber  PageNumber  PageSize    SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10     2      1      1      10         3           5           1
11     2      1      2      11         3           5           1
12     2      1      3      12         3           5           1
13     2      2      1      13         3           5           1
14     2      2      2      14         3           5           1

(5 row(s) affected)

1
फी, जब SET SHOWPLAN_ALL ऑन मेथड 1 का प्रयोग किया गया था, तो टोटलसुब्रीकॉस्ट की कुल संख्या 0.08424953 थी, जबकि मेथड 0.0227153 पर था। विधि 2 तीन गुना बेहतर थी।
के.एम.

1
@ ग्रिड, विधि 1 और 2 दोनों ही सीटीई का उपयोग करते हैं, जिस तरह से वे पृष्ठबद्ध करते हैं और पंक्तियों को क्रमबद्ध करते हैं। मुझे यकीन है कि क्यों नहीं इस वास्तविक सवाल सवाल क्यों भिन्न है कर रहा हूँ कि (ओपी द्वारा इस सवाल का जवाब में) करने के लिए ओपी लिंक, लेकिन मेरे जवाब यह है कि ओपी को संदर्भित करता है लिंक के आधार पर काम करने वाले कोड बनाता है
केएम।

1
धन्यवाद, मैं पुराने पोस्ट और इस उत्तरों की तुलना करने की कोशिश कर रहा हूं। [मुझे नहीं पता कि यह कैसे प्रारूपित किया जाता है] यहाँ तोमलक द्वारा दिया गया उत्तर है। stackoverflow.com/questions/230058?sort=votes#sort-top क्या यह गलत है? यदि वह उत्तर का केवल आधा ही पोस्ट करता है, तो मैं अपनी क्वेरी करने के अपने बेहतर प्रदर्शन के तरीके के साथ कैसे आगे बढ़ूंगा? कृपया मुझे आगे बढ़ने के लिए कुछ और प्रकाश दें .. धन्यवाद

@ जोसेफ, आपके द्वारा प्रदान किए गए लिंक में चयनित उत्तर ( stackoverflow.com/questions/230058?sort=votes#sort-top ) कार्य कोड से भिन्न होता है कि प्रश्न पूछने वाला व्यक्ति उनके उत्तर में काम करने के लिए प्रदान करता है: stackoverflow.com/ प्रश्न / 230058 /… यदि आप उस उत्तर को पढ़ते हैं तो आपको उनके कोड का लिंक दिखाई देगा: pastebin.com/f26a4b403 और उनके संस्करण का एक लिंक Tomalak का: pastebin.com/f4db89a8e मेरे उत्तर में मैं प्रत्येक संस्करण का एक कार्यशील संस्करण प्रदान करता हूं। टेबल चर
के.एम.

2
WITH MyCte AS 
(
    select 
       employee_id,
       RowNum = row_number() OVER (order by employee_id)
    from V_EMPLOYEE 
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0
ORDER BY employee_id

-1
 select salary from (
 select  Salary, ROW_NUMBER() over (order by Salary desc) rn from Employee 
 ) t where t.rn = 2

3
ढेर अतिप्रवाह में आपका स्वागत है! हालांकि यह कोड स्निपेट समाधान हो सकता है, स्पष्टीकरण सहित वास्तव में आपके पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
जोहान

कृपया भविष्य के पाठकों के लाभ के लिए कोड स्निपेट में कुछ संदर्भ जोड़ें ।
देबजनबी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.