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

वर्डप्रेस प्रश्नों को जोड़ती है

यह उत्तर का अद्यतन संस्करण है, जो पिछले वाले की तुलना में अधिक लचीला है।

यहाँ एक SQL UNION का उपयोग करने का एक विचार दिया गया है :

  • हम posts_clauses . के डेटा का उपयोग कर सकते हैं posts_request . से SQL क्वेरी को फिर से लिखने के लिए फ़िल्टर करें छानना

  • हम WP_Query . का विस्तार करते हैं हमारे लक्ष्य को प्राप्त करने के लिए वर्ग। हम वास्तव में ऐसा दो बार करते हैं:

    • WP_Query_Empty :प्रत्येक उप-प्रश्नों की उत्पन्न SQL क्वेरी प्राप्त करने के लिए, लेकिन डेटाबेस क्वेरी किए बिना।
    • WP_Query_Combine :पोस्ट लाने के लिए।
  • निम्नलिखित कार्यान्वयन N combining के संयोजन का समर्थन करता है उप-प्रश्न।

यहां दो डेमो हैं:

डेमो #1:

मान लें कि आपके पास छह पद हैं, दिनांक के अनुसार आदेशित (DESC):

CCC
AAA
BBB
CCC
YYY
ZZZ
XXX 

जहां XXX , YYY और ZZZ DT=2013-12-14 13:03:40 . से पुराने हैं ।

आइए हमारे पोस्ट को ऑर्डर करें ताकि पोस्ट DT . के बाद प्रकाशित हों DT . से पहले शीर्षक (ASC) और पोस्ट के द्वारा आदेश दिया जाता है शीर्षक (DESC) द्वारा आदेशित हैं:

AAA
BBB
CCC
ZZZ
YYY
XXX 

तब हम निम्नलिखित का उपयोग कर सकते हैं:

/**
 * Demo #1 - Combine two sub queries:
 */

$args1 = array(
    'post_type'  => 'post',
    'orderby'    => 'title',
    'order'      => 'ASC',
    'date_query' => array(
        array( 'after' => '2013-12-14 13:03:40' ),
    ),
);

$args2 = array(
    'post_type'  => 'post',
    'orderby'    => 'title',
    'order'      => 'DESC',
    'date_query' => array(
        array( 'before' => '2013-12-14 13:03:40', 'inclusive' => TRUE ),    
    ),
);

$args = array( 
   'posts_per_page' => 1,
   'paged'          => 1,
   'sublimit'       => 1000,
   'args'           => array( $args1, $args2 ),
);

$results = new WP_Combine_Queries( $args );

यह निम्न SQL क्वेरी उत्पन्न करता है:

SELECT SQL_CALC_FOUND_ROWS * FROM ( 
    ( SELECT wp_posts.* 
        FROM wp_posts 
        WHERE 1=1 
            AND ( ( post_date > '2013-12-14 13:03:40' ) ) 
            AND wp_posts.post_type = 'post' 
            AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
            ORDER BY wp_posts.post_title ASC 
            LIMIT 1000
    ) 
    UNION 
    ( SELECT wp_posts.* 
        FROM wp_posts 
        WHERE 1=1 
        AND ( ( post_date <= '2013-12-14 13:03:40' ) ) 
        AND wp_posts.post_type = 'post' 
        AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
        ORDER BY wp_posts.post_title DESC 
        LIMIT 1000
    ) 
) as combined LIMIT 0, 10 

डेमो #2:

यहां आपका उदाहरण है:

/**
 * Demo #2 - Combine two sub queries:
 */

$today = date( 'm/d/Y', strtotime( 'today' ) );

$args1 = array(
    'post_type'      => 'workshops',
    'meta_key'       => 'select_dates_0_workshop_date',
    'orderby'        => 'meta_value',
    'order'          => 'ASC',
    'meta_query'     => array(
        array(
            'key'         => 'select_dates_0_workshop_date',
            'value'       => $today,
            'compare'     => '>=',
            'type'        => 'CHAR',
        ),
    )
);

$args2 = array(
    'post_type'      => 'workshops',
    'meta_key'       => 'select_dates_0_workshop_date',
    'orderby'        => 'meta_value',
    'order'          => 'DESC',
    'meta_query'     => array(
        array(
            'key'         => 'select_dates_0_workshop_date',
            'value'       => $today,
            'compare'     => '<',
            'type'        => 'CHAR',
        ),
    )
);

$args = array( 
   'posts_per_page' => 5,
   'paged'          => 4,
   'sublimit'       => 1000,
   'args'           => array( $args1, $args2 ),
);

$results = new WP_Combine_Queries( $args );

इससे आपको इस तरह की एक क्वेरी मिलनी चाहिए:

SELECT SQL_CALC_FOUND_ROWS * FROM ( 
    ( SELECT wp_posts.* 
        FROM wp_posts 
        INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 
        INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
        WHERE 1=1 
            AND wp_posts.post_type = 'workshops' 
            AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') 
            AND (wp_postmeta.meta_key = 'select_dates_0_workshop_date' AND (mt1.meta_key = 'select_dates_0_workshop_date' AND CAST(mt1.meta_value AS CHAR) >= '05/16/2014') ) 
            GROUP BY wp_posts.ID 
            ORDER BY wp_postmeta.meta_value ASC
            LIMIT 1000 
        ) 
    UNION 
    ( SELECT wp_posts.* 
        FROM wp_posts 
        INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 
        INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
        WHERE 1=1 
            AND wp_posts.post_type = 'workshops' 
            AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') 
            AND (wp_postmeta.meta_key = 'select_dates_0_workshop_date' AND (mt1.meta_key = 'select_dates_0_workshop_date' AND CAST(mt1.meta_value AS CHAR) < '05/16/2014') ) 
            GROUP BY wp_posts.ID 
            ORDER BY wp_postmeta.meta_value DESC 
            LIMIT 1000 
        ) 
) as combined LIMIT 15, 5

डेमो #3:

हम दो से अधिक उप प्रश्नों को भी जोड़ सकते हैं:

/**
 * Demo #3 - Combine four sub queries:
 */

$args = array( 
   'posts_per_page' => 10,
   'paged'          => 1,
   'sublimit'       => 1000,
   'args'           => array( $args1, $args2, $args3, $args4 ),
);

$results = new WP_Combine_Queries( $args );

कक्षाएं:

यहां हमारे डेमो क्लासेस हैं:

/**
 * Class WP_Combine_Queries
 * 
 * @uses WP_Query_Empty
 * @link https://stackoverflow.com/a/23704088/2078474
 *
 */

class WP_Combine_Queries extends WP_Query 
{
    protected $args    = array();
    protected $sub_sql = array();
    protected $sql     = '';

    public function __construct( $args = array() )
    {
        $defaults = array(
            'sublimit'       => 1000,
            'posts_per_page' => 10,
            'paged'          => 1,
            'args'           => array(),
        );

        $this->args = wp_parse_args( $args, $defaults );

        add_filter( 'posts_request',  array( $this, 'posts_request' ), PHP_INT_MAX  );

        parent::__construct( array( 'post_type' => 'post' ) );
    }

    public function posts_request( $request )
    {
        remove_filter( current_filter(), array( $this, __FUNCTION__ ), PHP_INT_MAX  );

        // Collect the generated SQL for each sub-query:
        foreach( (array) $this->args['args'] as $a )
        {
            $q = new WP_Query_Empty( $a, $this->args['sublimit'] );
            $this->sub_sql[] = $q->get_sql();
            unset( $q );
        }

        // Combine all the sub-queries into a single SQL query.
        // We must have at least two subqueries:
        if ( count( $this->sub_sql ) > 1 )
        {
            $s = '(' . join( ') UNION (', $this->sub_sql ) . ' ) ';

            $request = sprintf( "SELECT SQL_CALC_FOUND_ROWS * FROM ( $s ) as combined LIMIT %s,%s",
                $this->args['posts_per_page'] * ( $this->args['paged']-1 ),
                $this->args['posts_per_page']
            );          
        }
        return $request;
    }

} // end class

/**
 * Class WP_Query_Empty
 *
 * @link https://stackoverflow.com/a/23704088/2078474
 */

class WP_Query_Empty extends WP_Query 
{
    protected $args      = array();
    protected $sql       = '';
    protected $limits    = '';
    protected $sublimit  = 0;

    public function __construct( $args = array(), $sublimit = 1000 )
    {
        $this->args     = $args;
        $this->sublimit = $sublimit;

        add_filter( 'posts_clauses',  array( $this, 'posts_clauses' ), PHP_INT_MAX  );
        add_filter( 'posts_request',  array( $this, 'posts_request' ), PHP_INT_MAX  );

        parent::__construct( $args );
    }

    public function posts_request( $request )
    {
        remove_filter( current_filter(), array( $this, __FUNCTION__ ), PHP_INT_MAX );
        $this->sql = $this->modify( $request );             
        return '';
    }

    public function posts_clauses( $clauses )
    {
        remove_filter( current_filter(), array( $this, __FUNCTION__ ), PHP_INT_MAX  );
        $this->limits = $clauses['limits'];
        return $clauses;
    }

    protected function modify( $request )
    {
        $request = str_ireplace( 'SQL_CALC_FOUND_ROWS', '', $request );

        if( $this->sublimit > 0 )
            return str_ireplace( $this->limits, sprintf( 'LIMIT %d', $this->sublimit ), $request );
        else
            return $request;
    }

   public function get_sql( )
    {
        return $this->sql;
    }

} // end class

फिर आप कक्षाओं को अपनी आवश्यकताओं के अनुसार समायोजित कर सकते हैं।

मैं यहाँ उल्लेखित ट्रिक का उपयोग करता हूँ UNION . के क्रम को सुरक्षित रखने के लिए उप क्वेरीज़। आप इसे हमारे sublimit . के साथ तदनुसार संशोधित कर सकते हैं पैरामीटर।

यह मुख्य प्रश्नों . के लिए भी काम करना चाहिए , posts_request . का उपयोग करके उदाहरण के लिए फ़िल्टर करें।

मुझे आशा है कि यह मदद करता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql के लिए अद्वितीय पहचानकर्ता के रूप में एकाधिक कॉलम का प्रयोग करें

  2. पहचान के लिए मौजूदा डेटाबेस से उपयोगकर्ताओं को कैसे प्राप्त करेंसर्वर4

  3. Django:कच्चे SQL क्वेरी के पैरामीटर पास करते समय MySQL सिंटैक्स त्रुटि

  4. MySQL GROUP BY... भिन्न मान समान फ़ील्ड होने के कारण

  5. mysql कस्टम वैश्विक परिभाषित चर