2013-05-16 1 views
5

मैं निम्नलिखित का चयन करें, जिसका लक्ष्य सभी ग्राहकों को जो दिन एक्स के बाद से कोई बिक्री नहीं हुई चयन करने के लिए, और भी पिछले बिक्री की तारीख और बिक्री की संख्या लाने है:एसक्यूएल - चयन से सभी कॉलम पास किए बिना समूह कैसे करें?

select s.customerId, s.saleId, max (s.date) from sales s 
group by s.customerId, s.saleId 
having max(s.date) <= '05-16-2013' 

लेकिन इस तरह से

19 | 300 | 26/09/2005 
19 | 356 | 29/09/2005 
27 | 842 | 10/05/2012 

दूसरे शब्दों में, पहले 2 लाइनों एक ही ग्राहक (आईडी 19), काश वह प्रत्येक ग्राहक के लिए केवल एक ही रिकॉर्ड प्राप्त करना चाहते हैं, जिसके साथ रिकॉर्ड होगा से कर रहे हैं: यह मेरे निम्नलिखित लाता है मामले में अधिकतम तिथि, इस सूची से दूसरा रिकॉर्ड। उस तर्क से, मुझे "समूह द्वारा" खंड से s.saleId को ले जाना चाहिए, लेकिन अगर मैं करता हूं, तो मुझे त्रुटि मिलती है: चयन सूची में अमान्य अभिव्यक्ति (या तो कुल कार्य में निहित नहीं है या खंड द्वारा ग्रुप)।

मैं उपयोग कर रहा हूँ Firebird 1.5

मैं यह कैसे कर सकते हैं?

उत्तर

8

ग्रुप द्वारा पंक्तियों के एक समूह के योग के द्वारा डेटा का सारांश दिया, लौटने एक पंक्ति प्रति समूह आप समेकित फ़ंक्शन max() का उपयोग कर रहे हैं, जो पंक्तियों के समूह के लिए एक कॉलम से अधिकतम मान वापस कर देगा।

चलो कुछ डेटा देखें। मैंने उस कॉलम का नाम बदल दिया जिसे आपने "दिनांक" कहा था।

create table sales (
    customerId integer not null, 
    saleId integer not null, 
    saledate date not null 
); 


insert into sales values 
(1, 10, '2013-05-13'), 
(1, 11, '2013-05-14'), 
(1, 12, '2013-05-14'), 
(1, 13, '2013-05-17'), 
(2, 20, '2013-05-11'), 
(2, 21, '2013-05-16'), 
(2, 31, '2013-05-17'), 
(2, 32, '2013-03-01'), 
(3, 33, '2013-05-14'), 
(3, 35, '2013-05-14'); 

आप

In another words, the first 2 lines are from the same customer(id 19), i wish he'd get only one record for each client, which would be the record with the max date, in the case, the second record from this list.

select s.customerId, max (s.saledate) 
from sales s 
where s.saledate <= '2013-05-16' 
group by s.customerId 
order by customerId; 

customerId max 
-- 
1   2013-05-14 
2   2013-05-16 
3   2013-05-14 

कहा कि तालिका क्या मतलब है? इसका मतलब है कि 16 मई को या उससे पहले की नवीनतम तारीख जिस पर ग्राहक "1" कुछ खरीदा था 14 मई था; 16 मई को या उससे पहले की नवीनतम तारीख जिस पर ग्राहक "2" कुछ खरीदा था 16 मई। यदि आप इस व्युत्पन्न तालिका का उपयोग जॉइन में करते हैं, तो यह अनुमानित परिणाम को लगातार अर्थ के साथ वापस कर देगा।

अब देखते हैं कि थोड़ा अलग प्रश्न देखें। MySQL इस वाक्यविन्यास को अनुमति देता है, और नीचे परिणाम सेट देता है।

select s.customerId, s.saleId, max(s.saledate) max_sale 
from sales s 
where s.saledate <= '2013-05-16' 
group by s.customerId 
order by customerId; 

customerId saleId max_sale 
-- 
1   10  2013-05-14 
2   20  2013-05-16 
3   33  2013-05-14 

आईडी "10" के साथ बिक्री 14 मई को नहीं हुई; यह 13 मई को हुआ था। इस प्रश्न ने झूठ पैदा की है।बिक्री लेनदेन की तालिका के साथ इस व्युत्पन्न तालिका में शामिल होने से त्रुटि मिल जाएगी।

यही कारण है कि फायरबर्ड सही ढंग से एक त्रुटि उठाता है। समाधान बिक्री खंड से बिक्री ड्रॉप है।

अब, यह सब कहकर, आप उन ग्राहकों को ढूंढ सकते हैं जिनके पास 16 मई से कोई बिक्री नहीं हुई है।

select distinct customerId from sales 
where customerID not in 
    (select customerId 
    from sales 
    where saledate >= '2013-05-16') 

और आप सही ग्राहक आईडी और "दाएं" बिक्री प्राप्त कर सकते हैं। (मैं कहता हूँ "सही" saleId, क्योंकि वहाँ सवाल में दिन पर एक से अधिक हो सकता है। मैं सिर्फ अधिकतम चुना है।)

select sales.customerId, sales.saledate, max(saleId) 
from sales 
inner join (select customerId, max(saledate) max_date 
      from sales 
      where saledate < '2013-05-16' 
      group by customerId) max_dates 
     on sales.customerId = max_dates.customerId 
     and sales.saledate = max_dates.max_date 
inner join (select distinct customerId 
      from sales 
      where customerID not in 
       (select customerId 
       from sales 
       where saledate >= '2013-05-16')) no_sales 
     on sales.customerId = no_sales.customerId 
group by sales.customerId, sales.saledate 

व्यक्तिगत रूप से, मुझे लगता है आम तालिका भाव यह आसान मुझे एसक्यूएल को पढ़ने के लिए कर इस तरह के बयान SELECT में खोए बिना।

with no_sales as (
    select distinct customerId 
    from sales 
    where customerID not in 
    (select customerId 
    from sales 
    where saledate >= '2013-05-16') 
), 
max_dates as (
    select customerId, max(saledate) max_date 
    from sales 
    where saledate < '2013-05-16' 
    group by customerId 
) 
select sales.customerId, sales.saledate, max(saleId) 
from sales 
inner join max_dates 
     on sales.customerId = max_dates.customerId 
     and sales.saledate = max_dates.max_date 
inner join no_sales 
     on sales.customerId = no_sales.customerId 
group by sales.customerId, sales.saledate 
0

आप प्रति केवल एक पंक्ति के लिए s.saleId (Max(s.saleId)) और Group By खंड

+1

हाँ, लेकिन केवल अगर उच्च बिक्री आईडी हमेशा एक नई तारीख का मतलब है। –

1

तो आप निम्न क्वेरी का उपयोग कर सकते हैं से हटाने ..

संपादित likeitlikeit द्वारा टिप्पणी के बाद किए गए परिवर्तनों Maxing कोशिश कर सकते हैं ग्राहक आईडी जब भी हमारे पास एक मामला होगा जहां हमारे पास कुछ शर्त वाले ग्राहक के लिए एकाधिक बिक्री आईडी है -

select x.customerID, max(x.saleID), max(x.x_date) from (
select s.customerId, s.saleId, max (s.date) x_date from sales s 
group by s.customerId, s.saleId 
having max(s.date) <= '05-16-2013' 
    and max(s.date) = (select max(s1.date) 
         from sales s1 
         where s1.customeId = s.customerId))x 

समूह द्वारा x.customerID

+0

यह क्वेरी आपको बिक्री आईडी देगी जिसमें आपकी स्थिति के लिए अधिकतम तिथि है। –

+0

यदि आप एक ही ग्राहक के लिए उसी दिन एक से अधिक बिक्री करते हैं तो यह काम नहीं करेगा। – likeitlikeit

+0

फिर इस मामले में आप क्या दिखाने की उम्मीद कर रहे हैं .. इसका मतलब है कि आप केवल बिक्री आईडी चाहते हैं? और इसके लिए क्या मूल्य होना चाहिए .. इसका मतलब है कि क्या आप इस मामले में अधिकतम बिक्री आईडी चाहते हैं? –

0

एक सबक्वेरी काम करना चाहिए, मैं अभी परीक्षण नहीं कर सकते लेकिन यह ठीक लगता है:

SELECT s.customerId, s.saleId, subq.maxdate 
FROM sales AS s 
    INNER JOIN (SELECT customerId, MAX(date) AS maxdate 
      FROM sales 
      GROUP BY customerId, saleId 
      HAVING MAX(s.date) <= '05-16-2013' 
     ) AS subq 
    ON s.customerId = subq.customerId AND s.date = subq.maxdate 
संबंधित मुद्दे

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