PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

अंतिम 10 तिथियों के लिए पंक्तियाँ प्राप्त करें

यह संदेहास्पद लगता है, लेकिन यह एक प्रश्न का नरक . है ।

मान्यताएं

crosstab() प्रश्न

शीर्ष प्रदर्शन और छोटी क्वेरी स्ट्रिंग प्राप्त करने के लिए (विशेषकर यदि आप इस क्वेरी को अक्सर चलाते हैं) मैं अतिरिक्त मॉड्यूल का सुझाव देता हूं tablefunc विभिन्न crosstab() प्रदान करना कार्य। बुनियादी निर्देश:

मूल क्वेरी

आपको पहले ये अधिकार प्राप्त करने होंगे।

पिछले 10 दिन:

SELECT DISTINCT date
FROM   book
WHERE  sid = 1
ORDER  BY date DESC
LIMIT  10;

विंडो फ़ंक्शन का उपयोग करके पिछले 10 दिनों के नंबर dense_rank() कोड> :

SELECT *
FROM  (
   SELECT name
        , dense_rank() OVER (ORDER BY date DESC) AS date_rnk
        , count
   FROM   book
   WHERE  sid = 1
   ) sub
WHERE  date_rnk < 11
ORDER  BY name, date_rnk DESC;

(इस क्वेरी में वास्तविक तिथियां शामिल नहीं हैं।)

आउटपुट कॉलम के लिए कॉलम नाम (पूर्ण समाधान के लिए):

SELECT 'bookname, "' || string_agg(to_char(date, 'DD/MM/YYYY'), '", "' ORDER BY date) || '"'
FROM  (
   SELECT DISTINCT date
   FROM   book
   WHERE  sid = 1
   ORDER  BY date DESC
   LIMIT  10
   ) sub;

स्थिर कॉलम नामों के साथ सरल परिणाम

यह आपके लिए काफी अच्छा हो सकता है - लेकिन हम परिणाम में वास्तविक तिथियां नहीं देखते हैं:

SELECT * FROM crosstab(
  'SELECT *
   FROM  (
      SELECT name
           , dense_rank() OVER (ORDER BY date DESC) AS date_rnk
           , count
      FROM   book
      WHERE  sid = 1
      ) sub
   WHERE  date_rnk < 11
   ORDER  BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
 ) AS (bookname text
     , date1 int, date2 int, date3 int, date4 int, date5 int
     , date6 int, date7 int, date8 int, date9 int, date10 int);

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

CREATE OR REPLACE FUNCTION crosstab_int10(text, text)
  RETURNS TABLE (bookname text
               , date1 int, date2 int, date3 int, date4 int, date5 int
               , date6 int, date7 int, date8 int, date9 int, date10 int)
  LANGUAGE C STABLE STRICT AS
'$libdir/tablefunc','crosstab_hash';

इस संबंधित उत्तर में विवरण:

तब आपका कॉल बन जाता है:

SELECT * FROM crosstab(
  'SELECT *
   FROM  (
      SELECT name
           , dense_rank() OVER (ORDER BY date DESC) AS date_rnk
           , count
      FROM   book
      WHERE  sid = 1
      ) sub
   WHERE  date_rnk < 11
   ORDER  BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
 );  -- no column definition list required!

डायनेमिक कॉलम नामों के साथ पूर्ण समाधान

आपका वास्तविक प्रश्न अधिक जटिल है, आप गतिशील कॉलम नाम भी चाहते हैं।
किसी दी गई तालिका के लिए, परिणामी क्वेरी इस तरह दिख सकती है:

SELECT * FROM crosstab_int10(
  'SELECT *
   FROM  (
      SELECT name
           , dense_rank() OVER (ORDER BY date DESC) AS date_rnk
           , count
      FROM   book
      WHERE  sid = 1
      ) sub
   WHERE  date_rnk < 11
   ORDER  BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
   ) AS t(bookname
        , "04/11/2015", "05/11/2015", "06/11/2015", "07/11/2015", "08/11/2015"
        , "09/11/2015", "10/11/2015", "11/11/2015", "15/11/2015", "17/11/2015");

डायनामिक कॉलम नामों को डिस्टिल करने में कठिनाई होती है। या तो क्वेरी स्ट्रिंग को हाथ से इकट्ठा करें, या (बल्कि बहुत अधिक) इस फ़ंक्शन को यह आपके लिए करने दें:

CREATE OR REPLACE FUNCTION f_generate_date10_sql(_sid int = 1) 
  RETURNS text
  LANGUAGE sql AS
$func$
SELECT format(
 $$SELECT * FROM crosstab_int10(
  'SELECT *
   FROM  (
      SELECT name
           , dense_rank() OVER (ORDER BY date DESC) AS date_rnk
           , count
      FROM   book
      WHERE  sid = %1$s
      ) sub
   WHERE  date_rnk < 11
   ORDER  BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
   ) AS ct(bookname, "$$
|| string_agg(to_char(date, 'DD/MM/YYYY'), '", "' ORDER BY date) || '")'
 , _sid)
FROM  (
   SELECT DISTINCT date
   FROM   book
   WHERE  sid = 1
   ORDER  BY date DESC
   LIMIT  10
   ) sub
$func$;

कॉल करें:

SELECT f_generate_date10_sql(1);

यह वांछित क्वेरी उत्पन्न करता है , जिसे आप बदले में निष्पादित करते हैं।

db<>fiddle यहां




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Psycopg2 :संग्रहीत कार्यविधि में एक तालिका बनाएँ Postgres

  2. सॉकेट फ़ाइल /var/pgsql_socket/.s.PGSQL.5432 माउंटेन लायन में गुम (OS X सर्वर)

  3. प्ले स्कैला नियंत्रक से जेसन कैसे वापस करें?

  4. हाइव या पोस्टग्रेज में विभिन्न कार्यों को कब करना है, यह निर्धारित करने के लिए विंडो फ़ंक्शन का उपयोग कैसे करें?

  5. एसक्यूएल - या शर्तों का क्रम मायने रखता है?