मेरे पास प्राथमिककी के बिना एक टेबल है। और मैं आईडी द्वारा समूहीकृत सबसे पुरानी तारीख की घटनाओं को प्राप्त करने की कोशिश कर रहा हूं।

Mytable का छोटा टुकड़ा इस तरह दिखता है:

|----------|------------------|-------------|
|    id    |       date       |    events   |
|----------|------------------|-------------|
|     1    |2020-04-11 3:44:20|     call    |
|----------|------------------|-------------|
|     3    |2020-04-21 7:59:06| appointment |
|----------|------------------|-------------|
|     1    |2020-04-17 1:14:32| appointment |
|----------|------------------|-------------|
|     2    |2020-04-10 3:41:17|   feedback  |
|----------|------------------|-------------|
|     1    |2020-04-23 1:36:13| appointment |
|----------|------------------|-------------|
|     3    |2020-04-12 4:55:38|     call    |
|----------|------------------|-------------|

यह वह परिणाम है जिसकी मुझे तलाश है:

|----------|------------------|-------------|
|    id    |       date       |    events   |
|----------|------------------|-------------|
|     1    |2020-04-11 3:44:20|     call    |
|----------|------------------|-------------|
|     2    |2020-04-10 3:41:17|   feedback  |
|----------|------------------|-------------|
|     3    |2020-04-12 4:55:38|     call    |
|----------|------------------|-------------|

मैं केवल उनके संबंधित मिन (तारीख) के लिए आईडी द्वारा ईवेंट प्राप्त करने का प्रयास कर रहा हूं लेकिन समस्या यह है कि मुझे ईवेंट चुनना है, लेकिन फिर मुझे ग्रुप बाय में ईवेंट जोड़ना होगा, इसलिए मैं केवल आईडी द्वारा ग्रुप नहीं कर सकता जैसा मैं चाहता हूं . मैंने कई अलग-अलग संस्करणों की कोशिश की है लेकिन यहां एक है:

SELECT id, MIN(date), events
FROM mydataset.mytable
GROUP BY id, events

कृपया ध्यान रखें कि मेरी टेबल इससे काफी बड़ी है। किसी भी मदद को बहुत, बहुत सराहा जाएगा।

0
Jones 4 अगस्त 2020, 23:31

5 जवाब

सबसे बढ़िया उत्तर

आप एकत्रीकरण का उपयोग कर सकते हैं:

select array_agg(t order by date asc limit 1)[ordinal(1)].*
from mydataset.mytable t
group by t.id;

या row_number() का उपयोग करने की अधिक पारंपरिक विधि:

select t.* except (seqnum)
from (select t.*, row_number() over (partition by id order by date) as seqnum
      from mydataset.mytable t
     ) t
where seqnum = 1;
1
Gordon Linoff 5 अगस्त 2020, 01:14

आप केवल विंडो फ़ंक्शन का उपयोग कर सकते हैं, जैसे कि min

Select distinct id, mindate, events from
    (
    Select id, date, min(date) over(partition by id)mindate, events from table
    ) x
0
Olga Romantsova 4 अगस्त 2020, 23:39

आपके पास uncorrelated सबक्वेरी के रूप में जो कुछ है उसे आप संशोधित कर सकते हैं

select *
from mytable 
where (id, date) in (select id, min(date)
                     from mytable
                     group by id);

अगर आपका DB window functions को सपोर्ट करता है तो आप भी कर सकते हैं

select distinct id, 
                min(date) over(partition by id) date,
                first_value(events) over (partition by id order by date asc) events
from mytable;

आउटपुट

+----+---------------------+----------+
| id |        date         |  events  |
+----+---------------------+----------+
|  1 | 2020-04-11 03:44:20 | call     |
|  2 | 2020-04-10 03:41:17 | feedback |
|  3 | 2020-04-12 04:55:38 | call     |
+----+---------------------+----------+
0
Isildur 4 अगस्त 2020, 23:55

व्युत्पन्न तालिका में शामिल होना बेहतर प्रदर्शन कर सकता है, esp। यदि आईडी और दिनांक अनुक्रमित हैं:

select m.*
 from mytable m
  join (select id, min(date) date
    from mytable
    group by id ) x
   on m.id = x.id
    and m.date = x.date
;
0
David G. Pickett 5 अगस्त 2020, 00:05

जोन्स की टिप्पणी के साथ गॉर्डन के उत्तर पर बनाया गया -

नीचे के संस्करण में उपनाम का उपयोग करने की आवश्यकता नहीं है और GROUP BY में केवल id के उपयोग की अनुमति है

#standardSQL
SELECT AS VALUE ARRAY_AGG(t ORDER BY date LIMIT 1)[ORDINAL(1)]
FROM `project.dataset.table` t
GROUP BY id
0
Mikhail Berlyant 5 अगस्त 2020, 01:23