2013-07-01 5 views
8

मुझे यकीन नहीं है कि निम्नलिखित चयन कथन का उपयोग करके निम्नलिखित किया जा सकता है, लेकिन मेरे पास दो टेबल हैं (समस्या के लिए आवश्यक डेटा के साथ छिड़काव)।जटिल क्वेरी

सूची आइटम

  • आईडी पूर्णांक (प्राथमिक)
  • मात्रा पूर्णांक

स्टॉक - सूची आइटम के शेयर में परिवर्तन शामिल हैं (शेयर इतिहास)

  • आईडी पूर्णांक (प्राथमिक)
  • inventory_item_id पूर्णांक (विदेशी कुँजी)
  • मात्रा पूर्णांक
  • बनाया datetime

स्टॉक में मात्रा है स्टॉक में परिवर्तन, जबकि ई सूची आइटम में मात्रा है कि आइटम की वर्तमान मात्रा

running कॉलम में सब कुछ

अब वापस आ जाएगी 0

SELECT 
inventory_item.id, 
(inventory_item.quantity - SUM(stock.quantity)) AS running 
FROM 
    stock 
     JOIN 
    inventory_item ON stock.inventory_item_id = inventory_item.id 
GROUP BY inventory_item.id 

प्रश्न है, मैं जानना चाहूंगा क्या है : क्या स्टॉक तालिका में सभी तिथियों का चयन करना संभव है जहां एक सूची का उपयोग करके inventory_item की चलती मात्रा शून्य हो जाती है?

मुझे पता है कि यह एक आइटम में सभी स्टॉक डेटा का चयन करके प्रोग्रामेटिक रूप से किया जा सकता है, और वर्तमान सूची आइटम मात्रा से स्टॉक मात्रा को अलग-अलग घटाना, जो स्टॉक में बदलाव से पहले मात्रा प्राप्त करेगा। क्या मैं इसे एक चयन के साथ कर सकता हूं?

+0

क्या inventory_item_id के दिए गए संयोजन के लिए कभी भी एक से अधिक रिकॉर्ड होंगे और बनाए गए? –

उत्तर

2

उस पर मेरी ले:

select 
    inventory_item_id `item`, 
    created `when` 
from 
    (select 
     @total := CASE WHEN @curr <> inventory_item_id 
        THEN quantity 
        ELSE @total+quantity END as running_total, 
     inventory_item_id, 
     created,     
     @curr := inventory_item_id 
    from 
     (select @total := 0) a 
     (select @curr := -1) b 
     (select inventory_item_id, created, quantity from stock order by inventory_item_id, created asc) c 
    ) running_total 
where running_total.running_total = 0; 

यह एक होने के रिश्तेदार लाभ दिया है करने के लिए केवल एक पास देने के लिए स्टॉक टेबलउस पर आकार और इंडेक्स के आधार पर जो अच्छी बात हो सकती है या नहीं भी हो सकती है।

5

(अद्यतन) मान लिया जाये कि inventory_item_id की दी गई संयोजन के लिए एक से अधिक रिकॉर्ड और बनाया वहाँ कभी नहीं होगा, की कोशिश:

SELECT i.id, 
     s.created, 
     i.quantity - COALESCE(SUM(s2.quantity),0) AS running 
FROM inventory_item i 
JOIN stock s ON s.inventory_item_id = i.id 
LEFT JOIN stock s2 ON s2.inventory_item_id = i.id and s.created < s2.created 
GROUP BY i.id, s.created 
HAVING running=0 
+0

चूंकि i.quantity नवीनतम मात्रा है, यह गलत है। मुझे लगता है कि आपको अपना 'रनिंग' फ़ील्ड 'SUM (s2.quantity) 'में बदलने की जरूरत है। फिर यह केवल नवीनतम न केवल सभी स्टॉक तिथियों के लिए सही परिणाम देगा। – Tom

+1

@ टॉम: मैंने आपके द्वारा उठाए गए बिंदु को ध्यान में रखने के लिए क्वेरी में संशोधन किया है। चल रहे कुल के रूप में अकेले 'stock.quantity' की राशि का उपयोग करना गलत होगा, क्योंकि इसका उपयोग स्टॉक में रखी गई मात्रा में * परिवर्तन * रखने के लिए किया जाता है - संक्षेप में यह हमें बताएगा कि कितना परिवर्तन हुआ था, लेकिन नहीं उस समय स्टॉक स्तर क्या था। –

+0

मैं स्टॉक का योग मान रहा था। मात्रा कुल चल रही थी क्योंकि उन्होंने कहा: "स्टॉक में मात्रा स्टॉक में बदलाव है, जबकि सूची वस्तु में मात्रा उस आइटम की वर्तमान मात्रा है चल रहे कॉलम में सबकुछ 0 वापस आ जाएगा "। शायद मैं इस गलत व्याख्या कर रहा हूँ? मुझे लगा कि स्टॉक टेबल में पहली प्रविष्टि शुरुआत स्टॉक होगी। – Tom

2

ऐसा करने का सबसे तार्किक ढंग से एक संचयी राशि के साथ है। लेकिन, MySQL उस का समर्थन नहीं करता है।

मेरी राय में स्पष्ट दृष्टिकोण, चलती मात्रा प्राप्त करने के लिए एक सहसंबंधित सबक्वायरी का उपयोग करना है। तो फिर यह चयन करने के लिए जहां यह 0 है एक where खंड के एक बहुत आसान है:

select i.* 
from (select i.*, 
      (select SUM(i2.inventory) 
       from inventory i2 
       where i2.inventory_item_id = i.inventory_item_id and 
        i2.created <= i.created 
      ) as RunningQuantity 
     from inventory i 
    ) i 
where RunningQuantity = 0; 
2

मेरा मानना ​​है कि यह इस के लिए एक आसान दृष्टिकोण है।

SELECT inventory_item.id, stock.created 

FROM inventory_item 

     JOIN stock ON stock.inventory_item_id = inventory_item.id 

WHERE (SELECT SUM(quantity) FROM stock WHERE created <= stock.created) = 0 
2

मैं एक प्रतिक्रिया समान एक चल कुल के आधार पर found here...

आप MySQL @variables साथ क्या कर सकते ध्वजांकित किया था, लेकिन डेटा पूर्व पूछे और आदेश दिया जा करने के लिए गतिविधि के डेटा द्वारा की जरूरत है। .. फिर प्रत्येक पंक्ति पर एक झंडा सेट करें जो नकारात्मक कारण बनता है और केवल उनको रखता है। जैसे

select 
     PreQuery.* 
    from 
     (select 
       s.id, 
       s.created, 
       @runBal := if(s.id = @lastID, @runBal - quantity, @i.quantity) as CurBal, 
       @lastID := s.id as IDToCompareNextEntry 
      from 
       stock s 
       join inventory_item ii 
        on s.inventory_item_id = ii.id, 
       (select @lastID := -1, 
         @runBal := 0) sqlvars 
      order by 
       s.id, 
       s.created DESC) PreQuery 
    where 
     PreQuery.CurBal < 0 

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

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