2012-11-16 5 views
11

मैं इस तरह कुछ expresion करने के लिए देख रहा हूँएक का चयन बयान के साथ, एक विशिष्ट श्रेणी के बीच पंक्तियों लौटें

SELECT TOP 10 columName FROM tableName 

(एसक्यूएल सर्वर 2008 का उपयोग कर) लेकिन बजाय इस बात का मैं 10 और 20 के बीच और मूल्यों की आवश्यकता मुझे आश्चर्य है कि केवल एक ही चयन कथन का उपयोग करके ऐसा करने का कोई तरीका है।

उदाहरण के लिए इस बेकार है:

SELECT columName FROM 
(SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName) AS alias 
WHERE RowNum BETWEEN 10 AND 20 

क्योंकि चयन के अंदर कोष्ठक पहले से ही सभी परिणाम लौटा रहा है, और मुझे लगता है कि से बचने के लिए, प्रदर्शन की वजह से देख रहा हूँ।

उत्तर

0

लाने/छोड़ने के लिए SQL Server 2012 का उपयोग करें!

SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty, UnitPrice, LineTotal 
FROM AdventureWorks2012.Sales.SalesOrderDetail 
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; 

एसक्यूएल सर्वर के पुराने संस्करणों के वर्णन के मुकाबले कुछ बेहतर नहीं है। शायद सीटीई का उपयोग करें, लेकिन एक अंतर बनाने की संभावना नहीं है।

WITH NumberedMyTable AS 
(
    SELECT 
     Id, 
     Value, 
     ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber 
    FROM 
     MyTable 
) 
SELECT 
    Id, 
    Value 
FROM 
    NumberedMyTable 
WHERE 
    RowNumber BETWEEN @From AND @To 

या, आप शीर्ष 10 पंक्तियों को हटा सकते हैं और फिर अगले 10 पंक्तियों मिलता है, लेकिन मैं किसी को भी दोगुना है कि क्या करना चाहते हैं।

+1

SQL सर्वर 2012 में अपग्रेड करना आम तौर पर "आपकी अंगुलियों को स्नैप नहीं" विकल्प नहीं है। और मैं तर्क दूंगा कि * SQL सर्वर के पुराने संस्करणों में बेहतर उत्तर हैं। उदाहरण के लिए, पंक्ति संख्याओं को लागू करते समय केवल * कुंजी * मानों को पुनर्प्राप्त क्यों न करें, फिर तालिका के साथ उस आउटपुट (जो * अधिक * स्किनर होगा) में शामिल हों? –

+0

@AaronBertrand, आप सही हैं।मैं पूरी तरह से सहमत हूं कि उन्नयन आसान नहीं है, लेकिन यदि ओपी इस कथन का बहुत उपयोग कर रहा है और वास्तव में प्रदर्शन के बारे में परवाह करता है, तो यह कुछ ऐसा है जिसे वह ध्यान में रख सकता है। – RAS

7

row_number के साथ एक चाल है जिसमें सभी पंक्तियों को क्रमबद्ध करने शामिल नहीं है।

इस प्रयास करें:

SELECT columName 
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (select NULL as noorder)) AS RowNum, * 
     FROM tableName 
    ) as alias 
WHERE RowNum BETWEEN 10 AND 20 

आप order by में एक निरंतर उपयोग नहीं कर सकते। हालांकि, आप एक अभिव्यक्ति का उपयोग कर सकते हैं जो निरंतर मूल्यांकन करता है। एसक्यूएल सर्वर इसे पहचानता है और पंक्तियों को ठीक तरह से समझा गया है, जैसा कि सामना करता है।

+0

मुझे यकीन नहीं है कि यह कैसे मदद कर सकता है। क्या यह मामला नहीं होगा कि यदि ROW_NUMBER() स्पष्ट सॉर्टिंग के बिना लागू किया गया है, तो पेजिंग बेकार होगी (मनमानी क्रम में प्रस्तुत की गई)? –

+0

मैंने पाया है कि इस निर्माण का उपयोग करते हुए पंक्ति पंक्तियां उत्पन्न की जाती हैं क्योंकि पंक्तियां उत्पन्न होती हैं। या, अधिक विशेष रूप से, तालिका का कोई मध्यवर्ती सॉर्टिंग नहीं होता है (कम से कम प्रदर्शन के संदर्भ में)। मैं आमतौर पर 'चयन INTO' का उपयोग करते समय पंक्तियों के लिए संख्यात्मक आईडी निर्दिष्ट करने के लिए इसका उपयोग करता हूं। और, हां, पंक्ति संख्या मनमाने ढंग से हैं, लेकिन प्रश्न के प्रश्नों में 'आदेश' खंड नहीं थे। –

+0

लेकिन फिर, अवलोकन <> गारंटी। मुझे यकीन है कि प्रेजेंटेशन ऑर्डर महत्वपूर्ण है, लेकिन आमतौर पर ब्रेवटी के लिए इन सवालों में से बाहर निकलता है - ऐसा नहीं क्योंकि वे उन उत्तरों को प्रोत्साहित करना चाहते हैं जो संभावित रूप से मनमाना परिणाम प्रदान कर सकते हैं। –

3

आपको क्यों लगता है कि SQL सर्वर संपूर्ण आंतरिक क्वेरी का मूल्यांकन करेगा? मान लें कि आपके सॉर्ट कॉलम को अनुक्रमित किया गया है, यह केवल पहले 20 मानों को पढ़ेगा। यदि आप वास्तव में परेशान हैं तो आप यह कर सकते हैं:

Select 
    Id 
From (
    Select Top 20 -- note top 20 
    Row_Number() Over(Order By Id) As RowNum, 
    Id 
    From 
    dbo.Test 
    Order By 
    Id 
) As alias 
Where 
    RowNum Between 10 And 20 
Order By 
    Id 

लेकिन मुझे पूरा यकीन है कि क्वेरी प्लान एक ही तरीका है।

(वास्तव में) हारून की टिप्पणी के अनुसार तय किया गया।

http://sqlfiddle.com/#!3/db162/6

+0

तकनीकी रूप से आप वहां एक ऑर्डर चाहते हैं। आंतरिक चयन ROW_NUMBER() द्वारा लागू किए गए क्रम में पंक्तियों को वापस करने के लिए * गारंटीकृत * नहीं है, भले ही आप ज्यादातर मामलों में यही देख सकें। यह भी ध्यान रखें कि आंतरिक क्वेरी अधिक से अधिक महंगी हो जाती है जब आप दूसरे, तीसरे, 500 वें पृष्ठ के माध्यम से जाते हैं। आदर्श रूप से एक समाधान रैखिक प्रदर्शन प्रदान करेगा। –

+0

आपको किसी स्टेटलेस तरीके से ऐसा करने के लिए सूचियों की सूची की आवश्यकता होगी। मुझे नहीं लगता कि SQL सर्वर में एक इंडेक्स संरचना है जो इंडेक्स में एनएच स्थान पर जाने के लिए निरंतर प्रदर्शन प्रदान करती है। यदि अंतर्निहित सेट अपरिवर्तनीय था, तो आप बेहतर कर सकते हैं, फिर आप पृष्ठ ऑफसेट को प्रीकंप्यूट कर सकते हैं और उन्हें एक अलग तालिका में स्टोर कर सकते हैं। बाहरी क्वेरी को ठीक करने के लिए ठीक करने के लिए धन्यवाद। – Laurence

+0

आंतरिक क्वेरी वास्तव में वह है जिसे ऑर्डर की आवश्यकता होती है (बाहरी प्रस्तुति उद्देश्यों के लिए करता है, लेकिन आंतरिक को सही पंक्ति चयन सुनिश्चित करने के लिए आंतरिक आवश्यकता होती है)। इसके अलावा मैं स्टेटलेस प्रदान करने के बारे में कुछ भी सुझाव नहीं दे रहा था ... उपयोगकर्ताओं ने उम्मीद की है कि स्क्रॉलिंग के दौरान अंतर्निहित डेटा बदल सकता है। लेकिन एनएच पृष्ठ * की तलाश करना * एसक्यूएल सर्वर में अपेक्षाकृत रैखिक हो सकता है, लेकिन यदि आप 'शीर्ष तालिका से शीर्ष 10 (पृष्ठ * पृष्ठबद्ध) चुनें (' –

0

एक और विकल्प

SELECT TOP(11) columName 
FROM dbo.tableName 
ORDER BY 
CASE WHEN ROW_NUMBER() OVER (ORDER BY someId) BETWEEN 10 AND 20 
    THEN ROW_NUMBER() OVER (ORDER BY someId) ELSE NULL END DESC 
0

तुम एक अस्थायी तालिका बना सकते हैं कि जिस तरह से आप की तरह चाहते हैं का आदेश दिया जाता है: ROWNUM के रूप में

चयन ROW_NUMBER() से अधिक (someId द्वारा आदेश) , * #N tempTable में tableName से ...

इस तरह आपके पास पंक्ति की एक क्रमबद्ध सूची है रों। और आंतरिक क्वेरी को कई बार करने के बजाय बाद के समय पंक्ति संख्या से पूछताछ कर सकते हैं।

संबंधित मुद्दे