2016-09-19 8 views
6

मैं शीर्ष एन समूहों के रिकॉर्ड का चयन करना चाहता हूं। मेरे डेटा इस तरह दिखता है:एन समूहों के सभी रिकॉर्ड कैसे चुनें?

टेबल 'धावक':

id gid status rtime 
    --------------------------- 
    100 5550 1   2016-08-19 
    200 5550 2   2016-08-22 
    300 5550 1   2016-08-30 
    100 6050 3   2016-09-01 
    200 6050 1   2016-09-02 
    100 6250 1   2016-09-11 
    200 6250 1   2016-09-15 
    300 6250 3   2016-09-19 

टेबल 'स्थिर'

id description env 
    ------------------------------- 
    100 something 1 somewhere 1 
    200 something 2 somewhere 2 
    300 something 3 somewhere 3 

इकाई आईडी (आईडी) अपने कॉलम में समूह के भीतर अद्वितीय लेकिन अद्वितीय नहीं है , क्योंकि समूह का एक उदाहरण नियमित रूप से उत्पन्न होता है। समूह आईडी (गीड) प्रत्येक इकाई को सौंपा गया है लेकिन एक से अधिक उदाहरण उत्पन्न नहीं करेगा।

अब, तालिकाओं को संयोजित करना और किसी विशिष्ट मूल्य से फ़िल्टर करना या फ़िल्टर करना आसान है, लेकिन उदाहरण के लिए, मैं पहले दो समूहों को समूह आईडी के बारे में सीधे प्रतिक्रिया के बिना कैसे चुनूं? अपेक्षित परिणाम होगा:

id gid description status rtime 
    -------------------------------------- 
    300 6250 something 2 3   2016-09-19 
    200 6250 something 1 1   2016-09-15 
    100 6250 something 3 1   2016-09-11 
    200 6050 something 2 1   2016-09-02 
    100 6050 something 1 3   2016-09-01 

अतिरिक्त प्रश्न: जब मैं इस तरह की एक समय सीमा के लिए फ़िल्टर:

[...] 
    WHERE runner.rtime BETWEEN '2016-08-25' AND '2016-09-16' 

वहाँ सुनिश्चित करने के लिए एक सरल तरीका है, कि समूहों काट नहीं कर रहे हैं लेकिन किसी के साथ दिखाई देते हैं उनके सभी रिकॉर्ड या बिल्कुल नहीं?

+0

आप दो प्रश्नों आवश्यकता होगी। उपरोक्त यह पता लगाने के लिए कि शीर्ष 2 समूह क्या हैं, और उसके बाद उन दो समूहों में सभी रिकॉर्ड प्राप्त करने के लिए उन 2 समूह आईडी का उपयोग करने के लिए एक मूल क्वेरी। –

+0

SQL सर्वर विंडोिंग फ़ंक्शंस, ROW_NUMBER, NTILE, आदि – SQLMason

उत्तर

0

आप ऐसा करने के लिए ROW_NUMBER() का उपयोग कर सकते हैं। सबसे पहले, रैंक समूहों के लिए एक प्रश्न बनाने के लिए:

SELECT gid, ROW_NUMBER() over (order by gid desc) as RN 
FROM  Runner 
GROUP BY gid 

फिर अपने अन्य जानकारी प्राप्त करने के एक व्युत्पन्न तालिका के रूप में उपयोग, और जहां खंड समूहों आप देखना चाहते हैं की संख्या के फिल्टर करने के लिए एक का उपयोग करें। उदाहरण के लिए, नीचे शीर्ष 5 समूहों वापसी होगी RN <= 5:

SELECT  id, R.gid, description, status, rtime 
FROM  (SELECT gid, ROW_NUMBER() over (order by gid desc) as RN 
      FROM  Runner 
      GROUP BY gid) G 
INNER JOIN Runner R on R.gid = G.gid 
INNER JOIN Statis S on S.id = R.id 
WHERE  RN <= 5 --Change this to see more or less groups 

तिथियों के बारे में अपने दूसरे प्रश्न के लिए, आप तो जैसे एक सबक्वेरी के साथ ऐसा कर सकते हैं:

SELECT * 
FROM Runner 
WHERE gid IN (SELECT gid 
       FROM Runner 
       WHERE rtime BETWEEN '2016-08-25' AND '2016-09-16') 
+0

दोनों प्रश्नों के लिए बहुत अच्छा जवाब देखें। धन्यवाद। – Xen

1

हमम। मुझे संदेह है कि यह वही कर सकता है जो आप चाहते हैं:

select top (1) with ties r.* 
from runner r 
order by min(rtime) over (partition by gid), gid; 

कम से कम, यह पूरा पहला समूह प्राप्त करेगा।

किसी भी मामले में, gidorder by में एक कुंजी के रूप में और top with ties का उपयोग करने का विचार शामिल है।

1

आप निम्नलिखित

कर सकते हैं
with report as(
select n.id,n.gid,m.description,n.status,n.rtime, dense_rank() over(order by gid desc) as RowNum 
from @table1 n 
inner join @table2 m on n.id = m.id) 

select id,gid,description,status,rtime 
from report 
where RowNum<=2 -- <-- here n=2 
order by gid desc,rtime desc 
यहाँ

एक काम demo

1

DENSE_RANK एक आदर्श समाधान यहाँ

Select * From 
(
select DENSE_RANK() over (order by gid desc) as D_RN, r.* 
from runner r 
) A 
Where D_RN = 1 
+0

यह समाधान दिलचस्प है। यह एन समूहों के सभी रिकॉर्ड्स को चुनने की समस्या को बिल्कुल हल नहीं करता है बल्कि ऑर्डर नंबर द्वारा एक विशिष्ट समूह के सभी रिकॉर्ड चुनता है। मैं इसका भी उपयोग कर सकता हूं, इसलिए इसके लिए धन्यवाद। – Xen

0

रैंकिंग कार्य (ROW_NUMBER, DENSE_RANK आदि) का उपयोग करने की आवश्यकता नहीं की तरह दिखता है।

SELECT r.id, gid, [description], [status], rtime 
FROM runner r 
INNER JOIN static s ON r.id = s.id 
WHERE gid IN (
    SELECT TOP 2 gid FROM runner GROUP BY gid ORDER BY gid DESC 
) 
ORDER BY rtime DESC; 

ही CTE का उपयोग कर:

WITH grouped 
AS 
(
    SELECT TOP 2 gid 
    FROM runner GROUP BY gid ORDER BY gid DESC 
) 
SELECT r.id, grouped.gid, [description], [status], rtime 
FROM runner r 
INNER JOIN static s ON r.id = s.id 
INNER JOIN grouped ON r.gid = grouped.gid 
ORDER BY rtime DESC; 
संबंधित मुद्दे