2013-02-13 49 views
10

यह मेरा कोड है:TSQL: COUNT (*) से अधिक (एक द्वारा आदेश)

USE [tempdb]; 
GO 

IF OBJECT_ID(N'dbo.t') IS NOT NULL 
BEGIN 
    DROP TABLE dbo.t 
END 
GO 

CREATE TABLE dbo.t 
(
    a NVARCHAR(8), 
    b NVARCHAR(8) 
); 
GO 

INSERT t VALUES ('a', 'b'); 
INSERT t VALUES ('a', 'b'); 
INSERT t VALUES ('a', 'b'); 
INSERT t VALUES ('c', 'd'); 
INSERT t VALUES ('c', 'd'); 
INSERT t VALUES ('c', 'd'); 
INSERT t VALUES ('c', 'd'); 
INSERT t VALUES ('e', NULL); 
INSERT t VALUES (NULL, NULL); 
INSERT t VALUES (NULL, NULL); 
INSERT t VALUES (NULL, NULL); 
INSERT t VALUES (NULL, NULL); 
GO 

SELECT a, b, 
    COUNT(*) OVER (ORDER BY a) 
FROM t; 

this page of BOL को, माइक्रोसॉफ्ट का कहना है कि: विभाजन से निर्दिष्ट नहीं है

हैं, फ़ंक्शन क्वेरी परिणाम के सभी पंक्तियों को एक समूह के रूप में सेट करता है।

तो मेरी समझ के आधार पर, अंतिम SELECT कथन मुझे निम्नलिखित परिणाम देगा। चूंकि सभी रिकॉर्ड एक समूह में मानते हैं, है ना?

a  b   
-------- -------- ----------- 
NULL  NULL  12 
NULL  NULL  12 
NULL  NULL  12 
NULL  NULL  12 
a  b  12 
a  b  12 
a  b  12 
c  d  12 
c  d  12 
c  d  12 
c  d  12 
e  NULL  12 

लेकिन वास्तविक परिणाम है:

a  b   
-------- -------- ----------- 
NULL  NULL  4 
NULL  NULL  4 
NULL  NULL  4 
NULL  NULL  4 
a  b  7 
a  b  7 
a  b  7 
c  d  11 
c  d  11 
c  d  11 
c  d  11 
e  NULL  12 

किसी कारण बताने के लिए मदद कर सकते हैं? धन्यवाद।

+0

मुझे गलत किया जा सकता है, लेकिन मुझे नहीं लगता कि COUNT (*) ओवर (फ़ील्ड द्वारा ऑर्डर) बिल्कुल काम करता है ... – sgeddes

+0

@bluefeet - यही मैंने सोचा - धन्यवाद ... – sgeddes

+0

यह काम करता है एसक्यूएलसेवर 2012 - http://sqlfiddle.com/#!6/fe2f9/7 –

उत्तर

28

यह एक चल कुल (इस कार्यक्षमता एसक्यूएल सर्वर में version 2012 जब तक लागू नहीं किया गया।)

ORDER BY खिड़की जब निर्दिष्ट नहीं UNBOUNDED PRECEDING और CURRENT ROW डिफ़ॉल्ट के रूप में साथ एकत्रित होने की परिभाषित करता है देता है। ROWS के बजाय SQL सर्वर less well performingRANGE विकल्प पर डिफ़ॉल्ट है।

वे RANGE संस्करण के लिए उस खिड़की में संबंधों के मामले में अलग-अलग अर्थ विज्ञान नहीं सिर्फ वर्तमान पंक्ति (और पूर्ववर्ती पंक्तियाँ) लेकिन यह भी वर्तमान पंक्ति के रूप में a का एक ही मूल्य के साथ किसी भी अतिरिक्त बंधे पंक्तियों भी शामिल है। यह नीचे दिए गए परिणामों में प्रत्येक द्वारा गिने गए पंक्तियों की संख्या में देखा जा सकता है।

SELECT a, 
     b, 
     COUNT(*) OVER (ORDER BY a 
         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Rows], 
     COUNT(*) OVER (ORDER BY a 
         RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Range], 
     COUNT(*) OVER() AS [Over()] 
    FROM t; 

रिटर्न

a  b  Rows  Range  Over() 
-------- -------- ----------- ----------- ----------- 
NULL  NULL  1   4   12 
NULL  NULL  2   4   12 
NULL  NULL  3   4   12 
NULL  NULL  4   4   12 
a  b  5   7   12 
a  b  6   7   12 
a  b  7   7   12 
c  d  8   11   12 
c  d  9   11   12 
c  d  10   11   12 
c  d  11   11   12 
e  NULL  12   12   12 

नतीजा यह है कि आप को छोड़ देते हैं दोनोंPARTITION BY और ORDER BY हो और एक खाली OVER() खंड (भी ऊपर दिखाए गए) का उपयोग करने की उम्मीद कर रहे प्राप्त करने के लिए।

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