2012-06-05 17 views
8

मैं निम्न डेटानकल प्रत्येक पंक्ति

Job Quantity Status Repeat 
1  100  OK  2 
2  400  HOLD 0 
3  200  HOLD 1 
4  450  OK  3 

प्रत्येक पंक्ति के लिए दोहराएँ स्तंभ में मान के आधार पर के साथ इस तालिका है में एक स्तंभ मान के आधार पर पंक्तियों, पंक्ति फिर से दोहराया जाना चाहिए। उदाहरण के लिए जॉब 1 के लिए, दोहराना मान 2 है इसलिए जॉब 1 को दो बार दोहराया जाना चाहिए।

परिणामी तालिका होना चाहिए

Job Quantity Status Repeat 
1  100  OK  2 
1  100  OK  2 
1  100  OK  2 
2  400  HOLD 0 
3  200  HOLD 1 
3  200  HOLD 1 
4  450  OK  3 
4  450  OK  3 
4  450  OK  3 
4  450  OK  3 

नीचे के रूप में किसी ने मुझे इस प्रश्न के साथ मदद कृपया कर सकते हैं?

मैं एसक्यूएल सर्वर

+1

क्या 'दोहराना' में संभावित मूल्यों पर कोई उचित सीमा है? – Quassnoi

+0

नहीं। कोई सीमा नहीं है – user1345260

+1

डाउनवोट क्यों? – Quassnoi

उत्तर

10

यह किसी भी व्यक्तिगत नौकरी (मेरे सिस्टम पर) के लिए 7,400 से अधिक दोहराव का समर्थन करेगा। यदि आपको और अधिक चाहिए, तो आप एक अलग सिस्टम टेबल या क्रॉस जॉइन का उपयोग कर सकते हैं।

DECLARE @d TABLE (Job INT, Quantity INT, Status VARCHAR(12), Repeat INT); 

INSERT @d SELECT 1, 100, 'OK' ,2 
UNION ALL SELECT 2, 400, 'HOLD',0 
UNION ALL SELECT 3, 200, 'HOLD',1 
UNION ALL SELECT 4, 450, 'OK' ,3; 

WITH x AS 
(
    SELECT TOP (SELECT MAX(Repeat)+1 FROM @d) rn = ROW_NUMBER() 
    OVER (ORDER BY [object_id]) 
    FROM sys.all_columns 
    ORDER BY [object_id] 
) 
SELECT * FROM x 
CROSS JOIN @d AS d 
WHERE x.rn <= d.Repeat + 1 
ORDER BY Job; 
+0

यह काम करता है। मैं एक नौसिखिया हूँ इसलिए आप इस प्रश्न को समझाने के बाद कृपया कृपया कर सकते हैं। मुझे – user1345260

+1

'इन' के साथ एक [सामान्य तालिका अभिव्यक्ति] (http://msdn.microsoft.com/en-us/library/ms175972.aspx) का प्रतिनिधित्व नहीं करता है। अंदर, हम केवल एक सिस्टम टेबल से संख्याओं का एक सेट खींचते हैं जो कि बहुत सारी पंक्तियों की गारंटी है (मुझे लगता है कि आपके मामले में 7,400 पर्याप्त होना चाहिए)। हम आपकी तालिका में सबसे बड़ा 'दोहराना 'मान से उस नंबर को सीमित करने के लिए' TOP' का उपयोग करते हैं। फिर उन संख्याओं का उपयोग करके हम एक क्रॉस जॉइन करते हैं ताकि हमारे पास प्रत्येक नंबर के लिए सीटीई से एक पंक्ति हो <<'प्रति नौकरी दोहराएं। और हम उस तरफ 1 जोड़ते हैं (यह सुनिश्चित करता है कि आप पंक्तियों को भी शामिल करें जहां 'दोहराएं = 0')। –

+0

धन्यवाद। यह बहुत उपयोगी है – user1345260

-1

उपयोग कर रहा हूँ आप संग्रहीत प्रक्रिया है जिससे इस क्वेरी करना होगा (कर्सर के रूप में) लिख सकते हैं और फिर आप नए अस्थायी तालिका भर सकते हैं के रूप में आप

CREATE FUNCTION [dbo].[GetRepeatJobs]() 
RETURNS 
@JobsRepeatTable TABLE (JobId int, JobName nchar(10)) 
AS 
BEGIN 
DECLARE @i int 
DECLARE @j int 
DECLARE @JobId int 
DECLARE @JobName nchar(10) 

DECLARE JobsCursor CURSOR FOR (select JobId, JobName, JobRepeat from jobs) 
OPEN JobsCursor 
FETCH NEXT FROM JobsCursor INTO @JobId, @JobName, @i 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @j = 0 
    WHILE @j < @i 
    BEGIN 
     INSERT INTO @JobsRepeatTable VALUES (@JobId, @JobName) 
     SELECT @j = @j+1  
    END 
    FETCH NEXT FROM JobsCursor INTO @JobId, @JobName, @i 
END 
RETURN 
END 

चाहते मेरे लिए एकदम सही काम करता है ।

+0

यह प्रदर्शन के लिए अच्छा नहीं है ... WHILE (बिना कर्सर के) का उपयोग करके प्रदर्शन में वृद्धि हो सकती है ... लेकिन सीटीई तालिका बहुत तेज है – maurox

5
DECLARE @repeats TABLE 
     (
     rn INT NOT NULL PRIMARY KEY 
     ); 

WITH q (rn, m) AS 
     (
     SELECT 1, MAX(repeat) + 1 
     FROM jobs 
     UNION ALL 
     SELECT rn + 1, m 
     FROM q 
     WHERE rn < m 
     ) 
INSERT 
INTO @repeats 
SELECT rn 
FROM q 

SELECT j.* 
FROM jobs j 
CROSS APPLY 
     (
     SELECT TOP (j.repeat + 1) 
       NULL 
     FROM @repeats 
     ) q (repeat) 

आप एक तालिका जो guaranteedly repeat की अधिकतम संभव मूल्य से अधिक रिकॉर्ड है है, तो आप @repeats से छुटकारा पाने और इसके बजाय कि तालिका का उपयोग कर सकते हैं।

0

मैं निम्न दृष्टिकोण पसंद करता हूं, क्योंकि यह क्वेरी के सफल होने के लिए बाह्य डेटा पर निर्भर नहीं है और काफी सीधे आगे है। मैंने डेटा तालिका को आरंभ करने के लिए हारून बर्ट्रैंड का कोड उपयोग किया है, लेकिन डेटा को दोहराने के तरीके पर मेरा दृष्टिकोण - इस दृष्टिकोण को आवश्यक रिकॉर्ड्स की तुलना में अधिक पंक्तियां रखने के लिए एक विशिष्ट तालिका की आवश्यकता नहीं है/बाहरी डेटा पर निर्भर नहीं है।

DECLARE @d TABLE (Job INT, Quantity INT, Status VARCHAR(12), Repeat INT); 

INSERT @d SELECT 1, 100, 'OK' , 2 
UNION ALL SELECT 2, 400, 'HOLD', 0 
UNION ALL SELECT 3, 200, 'HOLD', 1 
UNION ALL SELECT 4, 450, 'OK' , 3; 

DECLARE @maxRecursion INT; 
SET @maxRecursion = (SELECT MAX(Repeat) 
         FROM @d);  

WITH Iterator AS 
(
    SELECT 1 AS Iterations 
    UNION ALL 
    SELECT Iterations + 1 FROM Iterator WHERE Iterations < @maxRecursion 
) 

SELECT A.* 
    FROM @d AS A 
RIGHT JOIN Iterator ON Iterator.Iterations <= (A.Repeat + 1) 
ORDER BY Job ASC 
OPTION (MAXRECURSION 0) 

चीयर्स!

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