2013-01-22 19 views
7

के लिए पंक्तियों की जेड% मैं इस तरह एक मेज है:एक के लिए पंक्तियों की एक्स% अद्यतन करने के लिए कैसे, पंक्तियों बी को की Y%, सी

Products 
(
    ID int not null primary key, 
    Type int not null, 
    Route varchar(20) null 
) 

मैं इस प्रारूप में ग्राहक पर एक सूची है :

Type=1, Percent=0.4, Route=A 
Type=1, Percent=0.4, Route=B 
Type=1, Percent=0.2, Route=C 
Type=2, Percent=0.5, Route=A 
Type=2, Percent=0.5, Route=B 
Type=3, Percent=1.0, Route=C 
...etc 

पूर्ण होने पर, मैं प्रकार का 40% आवंटित करने के लिए मार्ग सी टाइप 2 उत्पादों की तो 50% का एक करना चाहते हैं 1 उत्पादों का एक करने के लिए, रूट बी को 40% और 20% और मार्ग बी, आदि के 50% प्रकार 2 उत्पादों

क्या एक ही अद्यतन में ऐसा करने का कोई तरीका है tatement?

यदि एक विशाल विवरण में नहीं है, तो यह प्रति एक प्रश्न या एक मार्ग में एक कथन में किया जा सकता है? वर्तमान में हम एक प्रति प्रकार + मार्ग कर रहे हैं, उपर्युक्त में से कोई भी सुधार होगा।

+0

"प्रतिशत" अपनी सूची में नहीं बल्कि है भ्रामक अगर संख्या जो निम्नानुसार है वह वास्तव में प्रतिशत नहीं है । –

+0

आप किस डीबीएमएस का उपयोग कर रहे हैं? साथ ही, क्या आप अपने वर्तमान समाधान के कोड या छद्म कोड पोस्ट कर सकते हैं? –

+0

एसक्यूएल सर्वर 2008. और 0.4 प्रतिशत कैसे नहीं है? 40.0 बेहतर है? मुझे लगता है कि 0.4 बेहतर है क्योंकि 0.4 * गिनती (*) अद्यतन करने के लिए पंक्तियों की संख्या है। – powlette

उत्तर

1

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

यहाँ सेटअप है:

create table products (id int not null primary key, "type" int not null, route varchar (20) null); 
create table clienttable ("type" int not null, percent number (10, 2) not null, route varchar (20) not null); 
insert into clienttable ("type", percent, route) values (1, 0.4, 'A'); 
insert into clienttable ("type", percent, route) values (1, 0.4, 'B'); 
insert into clienttable ("type", percent, route) values (1, 0.2, 'C'); 
insert into clienttable ("type", percent, route) values (2, 0.5, 'A'); 
insert into clienttable ("type", percent, route) values (2, 0.5, 'B'); 
insert into clienttable ("type", percent, route) values (3, 1.0, 'C'); 

insert into products (id, "type", route) values (1, 1, null); 
insert into products (id, "type", route) values (2, 1, null); 
insert into products (id, "type", route) values (3, 1, null); 
insert into products (id, "type", route) values (4, 1, null); 
insert into products (id, "type", route) values (5, 1, null); 
insert into products (id, "type", route) values (6, 1, null); 
insert into products (id, "type", route) values (7, 1, null); 
-- 7 rows for product type 1 so we will expect 3 of route A, 3 of route B, 1 of route C (rounded) 

insert into products (id, "type", route) values (8, 2, null); 
insert into products (id, "type", route) values (9, 2, null); 
insert into products (id, "type", route) values (10, 2, null); 
insert into products (id, "type", route) values (11, 2, null); 
insert into products (id, "type", route) values (12, 2, null); 
-- 5 rows for product type 2 so we will expect 3 of route A and 2 of route B (rounded) 

insert into products (id, "type", route) values (13, 3, null); 
insert into products (id, "type", route) values (14, 3, null); 
-- 2 rows for product type 3 so we will expect 2 of route C 

और यहाँ बयान

select prods.id, prods."type", client.route cr from 
(
select 
p.id, 
p."type", 
row_number() over (partition by p."type" order by p.id)/count (*) over (partition by p."type") cum_ratio 
from 
products p 
) prods 
inner join 
(
select "type", route, nvl (lag (cum_ratio, 1) over (partition by "type" order by route), 0) ratio_start, cum_ratio ratio_end from 
(select "type", route, sum (rr) over (partition by "type" order by route) cum_ratio 
from (select c."type", c.route, ratio_to_report (c.percent) over (partition by "type") rr from clienttable c))) client 
on prods."type" = client."type" 
and prods.cum_ratio >= client.ratio_start and prods.cum_ratio < client.ratio_end 

यह निम्न परिणाम देता है: -

+----+------+----+ 
| ID | type | CR | 
+----+------+----+ 
| 1 | 1 | A | 
| 2 | 1 | A | 
| 3 | 1 | B | 
| 4 | 1 | B | 
| 5 | 1 | B | 
| 6 | 1 | C | 
| 8 | 2 | A | 
| 9 | 2 | A | 
| 10 | 2 | B | 
| 11 | 2 | B | 
| 13 | 3 | C | 
+----+------+----+ 
0

अगर इसी तरह की सुविधा एसक्यूएल सर्वर में मौजूद कैसे की तरह

--For updating type 1, set every route for type 1 as null. 

UPDATE MyTable 
SET [Route] = null 
WHERE [Type] = '1' 

--Update Route A(40%) 
DECLARE @myVal int; 
SET @myVal =CAST(0.4*(SELECT COUNT(*) FROM myTable WHERE [Type]='1') AS INT); 
WITH tab AS 
    (
    SELECT TOP (@myVal) * 
    FROM myTable 
    ) 
UPDATE tab 
SET  [Route] = 'A' 
WHERE [Route] is null 

--Update Route B (40%) 
DECLARE @myVal int; 
SET @myVal =CAST(0.4*(SELECT COUNT(*) FROM myTable WHERE [Type]='1') AS INT); 
WITH tab AS 
    (
    SELECT TOP (@myVal) * 
    FROM myTable 
    ) 
UPDATE tab 
SET  [Route] = 'B' 
WHERE [Route] is null 


--Update Route C (20%) 
DECLARE @myVal int; 
SET @myVal =CAST(0.2*(SELECT COUNT(*) FROM myTable WHERE [Type]='1') AS INT); 
WITH tab AS 
    (
    SELECT TOP (@myVal) * 
    FROM myTable 
    ) 
UPDATE tab 
SET  [Route] = 'C' 
WHERE [Route] is null 
+0

शायद मैं इसे नहीं देख रहा हूं, लेकिन क्या यह अभी भी प्रति मार्ग प्रति प्रकार एक अपडेट नहीं है जिसे मैं पहले से कर रहा हूं? साथ ही, आप एक टेबल से "शीर्ष एक्स प्रतिशत का चयन" कर सकते हैं ताकि आप गिनती चरणों को छोड़ सकें। मैं समाधान सोच रहा हूं, अगर कोई है, तो एक बड़ा मामला बयान होगा। – powlette

+0

हाँ। यह प्रत्येक अद्यतन कथन के लिए एक प्रकार/मार्ग अद्यतन करता है। – arunlalam

0

कुछ के बारे में मैं नहीं जानता। ओरेकल में सैंपल क्लॉज है। क्वेरी नीचे एक मेज से पंक्तियों का 10% का चयन करता है:

SELECT empno 
    FROM scott.emp 
SAMPLE (10) 
/

फिर अपने अद्यतन आसान होगा ... हो सकता है कि ख़ाली एसक्यूएल सर्वर में इसी तरह से मौजूद है। आप पंक्तियों या डेटा को तब भी गणना कर सकते हैं जब कैल्क प्रतिशत अपडेट करें ...

+0

टिप्पणियों में, मैंने कहा कि हम इसे एक लूप में कर रहे हैं: अद्यतन उत्पादों को सेट करें = 'ए' जहां टाइप = 1 और आईडी (उत्पादों से शीर्ष 40 प्रतिशत का चयन करें जहां टाइप = 1 और मार्ग शून्य है) तो अद्यतन मुश्किल नहीं है, लेकिन मैं अद्यतनों की संख्या को कम करना चाहता हूं। – powlette

0
WITH po AS 
    (SELECT 
     ID, 
     Type, 
     ROW_NUMBER() OVER (PARTITION BY Type 
          ORDER BY ID 
         ) AS Rn, 
     COUNT(*) OVER (PARTITION BY Type) AS CntType 
    FROM 
      Products 
)  
, ro AS 
    (SELECT 
     Type, 
     Route, 
     (SELECT SUM(rr.Percent) 
      FROM Route AS rr 
      WHERE rr.Type = r.Type 
      AND rr.Route <= r.Route 
     ) AS SumPercent 
    FROM 
      Routes AS r 
) 
UPDATE p 
SET p.Route = 
      (SELECT MIN(ro.Route) 
       FROM ro 
       WHERE ro.Type = po.Type 
       AND ro.SumPercent >= po.Rn/po.CntType 
      ) 
FROM Products AS p 
    JOIN 
     po ON po.ID = p.ID ;