I need to build a WP_Query that filters the posts by some Advanced Custom Fields. The following bullet-points describe the functionality needed:
Today is greater than start_date and less than 'end_date'.
If today is the 'start_date', test if the the time is greater than the 'start_time'.
If today is the 'end_date', text if the time is less than the 'end_time'.
Retrieve only the first post, ordered by custom field 'priority'.
I am struggling to build the typical WHERE clausule, like:
SELECT * FROM x WHERE (
( 'start_date' < today AND 'end_date' > today )
OR
( 'start_date' = today AND 'start_hour' < now )
OR
( 'end_date' = today AND 'end_hour' > now )
)
ORDER BY y
LIMIT 0,1;
I have been some time thinking about it, I thought it would be possible by nesting meta_queries in the WP_Query args... Didn't work (see args underneath).
$now_date = date('Ymd');
$now_time = date('Hi');
$args = array(
'post_type' => 'post',
'cat' => 4, /* Bulletin */
'posts_per_page' => 1,
'post_parent' => 0,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'bu_from',
'compare' => '<',
'value' => $now_date,
'type' => 'NUMERIC'
),
array(
'key' => 'bu_to',
'compare' => '>',
'value' => $now_date,
'type' => 'NUMERIC'
)
),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'bu_from',
'compare' => '=',
'value' => $now_date,
'type' => 'NUMERIC'
),
array(
'key' => 'bu_from_time',
'compare' => '<=',
'value' => $now_time,
'type' => 'NUMERIC'
)
),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'bu_to',
'compare' => '=',
'value' => $now_date,
'type' => 'NUMERIC'
),
array(
'key' => 'bu_to_time',
'compare' => '>=',
'value' => $now_time,
'type' => 'NUMERIC'
)
)
),
'meta_key' => 'bu_priority',
'orderby' => 'meta_value',
'order' => 'ASC'
);
REQUEST that ignores all the meta_query:
/* Taken from var_dump($the_query); */
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
WHERE 1=1
AND wp_posts.post_parent = 0
AND ( wp_term_relationships.term_taxonomy_id IN (4) )
AND wp_posts.post_type = 'post'
AND ((wp_posts.post_status = 'publish'))
AND (wp_postmeta.meta_key = 'bu_priority' )
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value ASC
LIMIT 0, 1
;
After reviewing with the management what exactly do we need... I changed all quite all the logic involved here.
<!-- START: BULLETIN -->
<?php
$args = array(
'post_type' => 'post',
'cat' => 4, /* Bulletin */
'posts_per_page' => -1,
'post_parent' => 0,
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'DESC'
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
// Start the Loop.
$added_cnt = 0;
$now = array( 'date' => date('md'), 'day' => date('N') );
$bulletins = array(
'1' => array(),
'2' => array(),
'3' => array(),
'4' => array(),
'5' => array()
);
while ( $the_query->have_posts() ) : $the_query->the_post();
if (
/* Scheduled by day and month */
(
( get_field('bu_schedule_by') == '1' )
&&
( get_field('bu_start_month').get_field('bu_start_day') <= $now['date'] )
&&
( get_field('bu_end_month').get_field('bu_end_day') >= $now['date'] )
)
||
/* Scheduled by day of the week */
(
( get_field('bu_schedule_by') == '2' )
&&
( in_array( $now['day'], get_field('bu_days_to_be_seen') ) )
)
) {
$bulletins[ get_field('bu_priority') ][ get_the_ID() ] = array();
$bulletins[ get_field('bu_priority') ][ get_the_ID() ][ 'title' ] = get_the_title();
$bulletins[ get_field('bu_priority') ][ get_the_ID() ][ 'subtitle' ] = get_field('bu_subtitle');
$bulletins[ get_field('bu_priority') ][ get_the_ID() ][ 'image' ] = get_field('bu_image');
$bulletins[ get_field('bu_priority') ][ get_the_ID() ][ 'content' ] = get_the_content();
$added_cnt++;
}
endwhile;
$bulletin = array();
$bu_priority = 1;
while ( ( $added_cnt > 0 ) && ( count($bulletin) == 0 ) ) {
if ( count($bulletins[$bu_priority]) > 0 ) {
$bulletin = reset($bulletins[$bu_priority]);
}
$bu_priority++;
}
$bu_image = $bulletin['image'];
echo '
<div class="section group section_opener custom_bulletin" style="margin-top: 4px; margin-bottom: 4px; padding: 0 !important;">
<div id="xmas_bg" class="col span_4_of_16"'.( !empty($bu_image) ? ' style="background-image: url('.$bu_image['url'].'); background-position: 50%; background-repeat: no-repeat; margin: 40px 0; height: 178px;"' : '' ).'></div>
<div id="xmas_title" class="col span_4_of_16" style="">
'.( $bulletin['title'] != '' ? '<h1 style="font-size: 28px; font-weight: 700;">'.$bulletin['title'].'</h1>' : '' ).'
'.( $bulletin['subtitle'] != '' ? '<h2 style="font-size: 23px; color: #c94446; font-weight: 300; margin-top: -8px;">'.$bulletin['subtitle'].'</h2>' : '' ).'
</div>
<div class="col span_1_of_16"></div>
<div id="xmas_copy" class="col span_6_of_16" style="padding: 80px 0; font-size: 14px !important;">
'.$bulletin['content'].'
</div>
<div class="col span_1_of_16"></div>
</div>
';
endif;
?>
<!-- END: BULLETIN -->
Related
SELECT users.name, users.registrationdate, users.city, users.status
FROM users, referrals
WHERE users.username= referrals.referrals AND referrals.username='user_name'
SELECT adearning, reffearning
FROM earnings WHERE usersname='user_name33'
How can I combine these two queries as if first query condition doesn't match and doesn't run.. then the second query should run and return some value if condition match
Try this
$query1 = $this->db->query("SELECT users.name, users.registrationdate, users.city, users.status
FROM users, referrals
WHERE users.username = referrals.referrals AND referrals.username='user_name'")
$result1 = $query1->result_array();
$query2 = $this->db->query("SELECT adearning, reffearning FROM earnings WHERE usersname='user_name33' ")
$result2 = $query2->result_array();
$dataArray = array_merge($result1, $result2);
if want to check the result, end of the line add this
print_r($dataArray);die;
On this it will print all of them in one array
Example
$result1 = array(
'0' => 'sjhccsd',
'1' => 'ddd',
'2' => 'df',
'3' => 'dfd',
);
$result2 = array(
'0' => 'sjhccsd',
'1' => 'ddd',
'2' => 'df',
'3' => 'dfd',
);
$dataArray = array_merge($result1, $result2);
print_r($dataArray);
Output : Array ( [0] => sjhccsd [1] => ddd [2] => df [3] => dfd [4] => sjhccsd [5] => ddd [6] => df [7] => dfd )
I have a working SQL query i want to figure out what would be the CakePHP query builder equivalent to work the exact same way?
SELECT customers.*, customer_reps.created FROM customers
LEFT JOIN customer_reps ON customer_reps.id =
(
SELECT id FROM customer_reps WHERE customer_id = customers.id
ORDER BY id ASC LIMIT 1
)
WHERE created >= 1475298000
AND created <= 1476217836
AND agents_id = 4
So essentially i am selecting all columns from "customers" and then i want only the "created" timestamp field of the FIRST "customer_reps" table for matching customer.
Documentation on CakePHP doesn't seem to explain how to do the select within select for sorting as this. I tried using the "hasMany" relational stuff but i was not able to find how to just get the "first" customer_reps entry to add to the main query for use in WHERE clause.
Thanks
try this code as a starting point you just need to group it by CustomerRep.customer_id because the order is already ascending if you're customer_reps table id is auto incremented already
$this->Customer->find('all', array(
'fields' => arrray(
'Customer.*',
'CustomerRep.created'
),
'joins' => array(
array(
'type' => 'LEFT',
'table' => 'customer_reps',
'alias' => 'CustomerRep',
'conditions' => 'Customer.id = CustomerRep.customer_id'
)
)
'conditions' => array(
'Customer.created >=' => '1475298000',
'Customer.created <=' => '1476217836',
'Customer.agentds_id' => 4
),
'group' => 'CustomerRep.customer_id'
));
Are you familiar with cakephp query builder? then if yes you should understand this flow
Step 1: SELECT customers.*, customer_reps.created FROM customers equivalent in cakephp is
$this->Customer->find('all', array(
'fields' => array(
'Customer.*',
'CustomerReply.created'
)
);
Note: CustomerReply.created is from join table of customer_reps which I just alias CustomerReply
Step 2: LEFT JOIN customer_reps ON customer_reps.id =
(
SELECT id FROM customer_reps WHERE customer_id = customers.id
ORDER BY id ASC LIMIT 1
) equivalent in cakephp is
'joins' => array(
array(
'table' => 'customer_reps',
'type' => 'left',
'alias' => 'CustomerReply',
'conditions' => array(
'CustomerReply.id = (SELECT id FROM customer_reps WHERE customer_id = Customer.id ORDER BY id ASC LIMIT 1)'
)
))
Step 3: WHERE created >= 1475298000
AND created <= 1476217836
AND agents_id = 4 equivalent in cakephp is
'conditions' => array(
'Customer.created >=' => 1475298000,
'Customer.created <=' => 1476217836,
'Customer.agents_id' => 4
)
);
so your cakephp query builder would be like this
$query = $this->Customer->find('all', array(
'fields' => array(
'Customer.*',
'CustomerReply.created'
),
'joins' => array(
array(
'table' => 'customer_reps',
'type' => 'left',
'alias' => 'CustomerReply',
'conditions' => array(
'CustomerReply.id = (SELECT id FROM customer_reps WHERE customer_id = Customer.id ORDER BY id ASC LIMIT 1)'
)
)),
'conditions' => array(
'Customer.created >=' => 1475298000,
'Customer.created <=' => 1476217836,
'Customer.agents_id' => 4
)
));
I want to all records from my postmeta table where meta_key = 'teljesitmeny' and meta_value between 0 and 150.
I make this query, but it's not working:
$argsg = array(
'post_type' => 'termek',
'meta_query' => array(
array(
'key' => 'teljesitmeny',
'value' => array(0, 150),
'compare' => 'BETWEEN'
),
),
);
$scheduled = '';
$scheduled = new WP_Query( $argsg );
It's only post one query, where meta_value is 150.
Datas in postmeta table:
Datas after execute the query:
What did i wrong?
Update:
I found the solution:
SELECT *
FROM `eopwrqjnc_postmeta`
WHERE `meta_key` LIKE 'teljesitmeny'
AND `meta_value`
BETWEEN CAST( 0 AS UNSIGNED )
AND CAST( 150 AS UNSIGNED )
LIMIT 0 , 30
How to left joing?
Left table
SELECT TYPE , days
FROM leavetypes
type days
anual 10
casual 6
sick 10
right table
SELECT sub_leave_type, (
SUM( working_days )
) AS used
FROM vacations
WHERE `user_id` = '1'
AND `from_date`
BETWEEN '2012-01-01'
AND '2012-12-31'
GROUP BY sub_leave_type
sub_leave_type used
anual 3
casual 6
actually I am doing this on cakephp this is my code.
$allleaves = $this->Leavetype->find('all', array(
'joins' => array(
array(
'table' => 'vacations',
'alias' => 'vacationsJoin',
'type' => 'left',
'conditions' => array('vacationsJoin.sub_leave_type = Leavetype.type')
)
),
'conditions' => array(
'vacationsJoin.user_id' => $_SESSION['Auth']['User']['id'],
'vacationsJoin.from_date BETWEEN ? and ?' => array(date('Y') . '-01-01',
date('Y') . '-12-31')
),
'fields' => array('type', 'days', '(SUM(working_days)) as used'),
'group' => 'sub_leave_type',
));
$this->set(compact('allleaves'));
This not out out that what i want, I want is all the row of left table and others from vacations table
Please read this query and change it according to your requirement
SELECT column_name(s)
FROM table_name1
LEFT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
I was correct the problem here is the answer. main problem was in GROUP
$allleaves = $this->Leavetype->find('all', array(
'joins' => array(
array(
'table' => 'vacations',
'alias' => 'vacationsJoin',
'type' => 'left',
'conditions' => array('vacationsJoin.sub_leave_type = Leavetype.type',
'vacationsJoin.user_id' => $_SESSION['Auth']['User']['id'],
'vacationsJoin.from_date BETWEEN ? and ?' => array(date('Y') . '-01-01',
date('Y') . '-12-31'),'vacationsJoin.status'=>'approved'
)
)
),
'fields' => array('type', 'days', '(SUM(working_days)) as used'),
'group' => 'type'
));
$this->set(compact('allleaves'));
Currently for my blog I get a list of years/dates using the following code:
$monthList = array(
1 => 'January',
2 => 'February',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'November',
11 => 'October',
12 => 'December'
);
$nav = array();
for ($year = 2009; $year <= date('Y'); $year++) {
foreach ($monthList as $id => $month) {
$this->tru->query->runRaw(array(
'name' => 'get-headline-count',
'sql' => 'SELECT
COUNT(id) as count
FROM
wp_'.$this->getId().'_posts
WHERE
post_status = \'publish\' AND
post_type = \'post\' AND
post_parent = \'0\' AND
YEAR(post_date) = '.$year.' AND
MONTH(post_date) = '.$id.'',
'connection' => 'article'
));
$temp = $this->tru->query->getArray('get-headline-count');
if ($temp['count'] > 0) {
$nav[$year][$id] = $temp['count'];
}
}
}
krsort($nav);
return array(
'month' => $monthList,
'nav' => $nav
);
This was all great at first, but now that I've got a few years worth of data and a few months this isn't going to cut it anymore. I've never done anything like this before, I usually deal with timestamps.
You can replace the loop with this one query
SELECT
YEAR(post_date) as yr, MONTH(post_date) as mn, COUNT(id) as count
FROM
wp_posts
WHERE
post_status = 'publish' AND
post_type = 'post' AND
post_parent = '0'
GROUP BY YEAR(post_date), MONTH(post_date)