2016-03-30 17 views
3

Müşterilerim ve işlemler tablosuna katılan bir sorgu sahibim, bu birleştirilmiş sorguyu jq olarak adlandırın. Her bir müşterinin alımlarının (işlemleri) sipariş zaman damgasına göre sıralamasını oluşturmak istiyorum (order_ts). Bu yüzden Satır veya dizin ile satırları birleştirmek> = N

SELECT customer_id, 
     order_id, 
     order_ts, 
     RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC), 
     amount 
FROM jq GROUP BY customer_id 
     ORDER BY customer_id; 

Şimdi, 5 alımları itibaren böyle devam yerine 5., 6., 7. içeren toplu tek sıra olacak ve istediğiniz yaptı. Özetlenen satır, 5'in order_id ve order_ts'u koruyacaktır. Bunu MS SQL Server ve Postgres'te nasıl yaparım? Seni doğru anladıysam

+0

almak için bir dış sorgusu kullanın Böyle bir şey deneyin ne olur toplamadan sonra 'order_id' ve' order_ts' için değer mi? –

+2

bazı örnek veriler ve beklenmedik sonuçlar lütfen. .. – Squirrel

+0

@FelixPamittan Soruyu şimdi güncelledim .. – menorah84

cevap

3

, sen CASE EXPRESSION ile bunu başarabilirsiniz:

SELECT customer_id,min(order_id),min(order_ts), CASE WHEN rnk < 5 then rnk else 5 end as rnk,sum(amount) 
FROM(
    SELECT customer_id, 
      order_id, 
      order_ts, 
      RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) as rnk, 
      amount 
    FROM jq) 
GROUP BY customer_id, 
     CASE WHEN rnk < 5 then rnk else 5 end 
ORDER BY customer_id 

Bu irade grup her RNK> 5 5 gibi, 1 grup olarak öylesine. Min order_id, ts'yi 5'i seçmem için seçtim. Bu doğru sonucu üretir rağmen

+2

Harika çözüm ve daha verimli. +1 –

+0

SELECT customer_id, min (order_id), min (order_ts), ** rnk **, toplam (miktar) ... GROUP BY ** customer_id **, herhangi bir sorun var mı, @sagi, Benim şüphem ** rnk ** GROUP BY –

+0

'a dahil değildir Teşekkürler @FelixPamittan – sagi

3

, sagi en answer daha verimlidir.


Sen RANK < 5 için sonuç ve filtre üzerinde SELECT kullanabilirsiniz. Sonra RANK >= 5

WITH Cte AS(
    SELECT 
     customer_id, 
     order_id, 
     order_ts, 
     RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) AS rnk, 
     amount 
    FROM jq 
    GROUP BY customer_id 
) 
SELECT 
    customer_id, 
    order_id, 
    order_ts, 
    rnk, 
    amount 
FROM Cte 
WHERE rnk < 5 

UNION ALL 

SELECT 
    customer_id, 
    MIN(order_id), 
    MIN(order_ts), 
    MIN(rnk), 
    SUM(amount) 
FROM Cte 
WHERE rnk >= 5 
GROUP BY customer_id 
ORDER BY customer_id; 

ilişkin toplu değerler üzerine bir UNION ALL yapmak * Bu SQL Server içindir

+0

Bunu jq'den sadece bir kez seçerek yapabilirsiniz. – sagi

+0

Yup. Bu, birçok olası çözümden sadece bir tanesidir. Seninkinden daha az verimli olsa da. –

1

bir sonuç

SELECT customer_id,(CASE WHEN ROW_NO <5 THEN ROW_NO ELSE 5 END) ROW_NO, SUM(amount) amount 
FROM (
    SELECT customer_id, 
      order_id, 
      order_ts, 
      RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) ROW_NO, 
     amount 
FROM jq 
) D 
GROUP BY customer_id,(CASE WHEN ROW_NO <5 THEN ROW_NO ELSE 5 END) 
+0

Gitmek için doğru yolu olsa da, doğru çıktıyı sağlamazsanız (kimlik ve tarih eksik) – sagi

+0

* min (order_id), min (order_ts) *, SUM (Amount) GROUP BY için geçerli bir veridir Müşteri Kimliği.? –

+0

Min (order_ts), geçerli, id çok geçerli değil, ancak daha büyük bir tarih varsayarak daha büyük id sonra evet demektir. – sagi

İlgili konular