yii query with 4 table on CActiveDataProvider - mysql

hi master i've 4 tables
-pegawai
-penilaian
-universitas
-jurusan
I usually use
SELECT u.nama_univ, j.singkatan, peg.* FROM pegawai AS peg LEFT JOIN penilaian AS pen ON pen.no_test=peg.no_test LEFT JOIN universitas AS u ON u.id=peg.univ_s1 LEFT JOIN jurusan AS j ON j.id=peg.bidang_s1
how to convert this query to yii ?
i've tried this code but it's not working well
$dataProvider = new CActiveDataProvider('Pegawai', array(
'criteria' => array(
'select' => array(
'`pen`.*',
'`u`.`nama_univ` AS `nama_univ`',
'`j`.`singkatan` AS `singkatan`'
),
'join' => 'JOIN `Penilaian` AS `pen` ON `pen`.`no_test` = `t`.`no_test`',
'join' => 'JOIN `Universitas` AS `u` ON `u`.`id` = `t`.`no_test`',
'join' => 'JOIN `Jurusan` AS `j` ON `j`.`id` = `t`.`no_test`',
)
));
but only one join there's execute

Do one thing you just print the criteria object like
$dataProvider = new CActiveDataProvider('Pegawai', array(
'criteria' => array(
'select' => array(
'`pen`.*',
'`u`.`nama_univ` AS `nama_univ`',
'`j`.`singkatan` AS `singkatan`'
),
'join' => 'JOIN `Penilaian` AS `pen` ON `pen`.`no_test` = `t`.`no_test`',
'join' => 'JOIN `Universitas` AS `u` ON `u`.`id` = `t`.`no_test`',
'join' => 'JOIN `Jurusan` AS `j` ON `j`.`id` = `t`.`no_test`',
)
));
echo "<pre>";
print_r($dataProvider); //Check the object or try to post it below
exit();

You have assigned 3 values to the same index of array ('join') so only the last one is stored.
Try:
$dataProvider = new CActiveDataProvider('Pegawai', array(
'criteria' => array(
'select' => array(
'`pen`.*',
'`u`.`nama_univ` AS `nama_univ`',
'`j`.`singkatan` AS `singkatan`'
),
'join' => 'JOIN `Penilaian` AS `pen` ON `pen`.`no_test` = `t`.`no_test` JOIN `Universitas` AS `u` ON `u`.`id` = `t`.`no_test` JOIN `Jurusan` AS `j` ON `j`.`id` = `t`.`no_test`',
)
));

Related

I need mysql query for wordpress for get ordered list

I need to get ordered list by three fields.
$sql = "
SELECT
SQL_CALC_FOUND_ROWS $wpdb->posts.ID
FROM
$wpdb->posts
INNER JOIN
$wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )
INNER JOIN
$wpdb->postmeta AS mt1 ON ( $wpdb->posts.ID = mt1.post_id )
WHERE
1=1
AND
(
( mt1.meta_key = 'pub_series' AND mt1.meta_value = 'Book' )
OR ( mt1.meta_key = 'pub_series' AND mt1.meta_value = 'Book chapter' )
OR ( mt1.meta_key = 'pub_series' AND mt1.meta_value = 'Journal Article' )
)
/*AND
(
mt3.meta_key = 'forthcoming'
)*/
AND
$wpdb->postmeta.meta_key = 'pub_year'
AND
$wpdb->posts.post_type = 'publication'
AND
$wpdb->posts.post_status = 'publish'
GROUP BY
$wpdb->posts.ID
ORDER BY
/*FIELD(mt3.meta_key, 'forthcoming') DESC,
FIELD(mt3.meta_value, 'null') DESC,*/
//FIELD($wpdb->postmeta.meta_value,1),
$wpdb->postmeta.meta_value DESC,
$wpdb->posts.post_date DESC
";
$total = count($wpdb->get_results($sql));
$offset = ( $paged * $posts_per_page ) - $posts_per_page;
$results = $wpdb->get_results( $sql . "
LIMIT
$offset, $posts_per_page" );
This is query ordered list by two fields: [custom_field] pub_year (possible values 2018, 2017...) and [delautl wp post date field] post_date. It is ok.
But now I need to show items with [custom_field] forthcoming = 1. Problem that there three states if this field:
- items with forthcoming = 1
- items with forthcoming = 0
- and items where custom field forthcoming not exist
I need to get ordered list with firts items forthcoming = 1 and other should be ordered by pub_year and date. How I can do this. Tell me if you need some more info. Thanks a lot.
I was get needed ordered list with adding for all posts meta key forthcoming = 0 with update meta method. So all fields have this field.
Next I was used wp_query meta_query args:
$pub_series = 'Book,Book chapter,Journal Article';
$search_args = array();
if (!empty($pub_series)) {
$pub_series_arr = explode(",", $pub_series);
if (!empty($pub_series_arr)) {
$search_args_add = array(
'relation' => 'OR'
);
foreach ($pub_series_arr as $pub_series_el) {
$adv_search_query_el = trim($pub_series_el);
if (!empty($adv_search_query_el)) {
$search_args_add[] = array(
'key' => 'pub_series',
'value' => $adv_search_query_el,
'compare' => '='
);
}
}
$search_args['meta_query'][] = $search_args_add;
}
}
$search_args['meta_query'][] = array(
'relation' => 'OR',
'forthcoming_clause' => array(
'key' => 'forthcoming',
'value' => '1'
),
'forthcoming_clause0' => array(
'key' => 'forthcoming',
'value' => '0'
)
);
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'publication',
'post_status' => 'publish',
'posts_per_page' => 10,
'orderby' => array(
'forthcoming_clause' => 'DESC',
'meta_value' => 'DESC',
'date' => 'DESC'
),
'meta_key' => 'pub_year',
'paged' => $paged
);
$args = array_merge($args, $search_args);
$posts = new WP_Query( $args );
if ( $posts->have_posts() ) : ...

cakephp 3.4 mySQL to orm convert

my Current MYSQL query is
SELECT
cl.user_id,
COUNT(q.id) as completed_questions,
(
SELECT
SUM(points)
FROM
completed_levels
WHERE
user_id = cl.user_id
)
as level_point
FROM
completed_levels cl
JOIN
questions q
on q.level_id = cl.level_id
GROUP BY
cl.user_id;
my current ORM is following i just not able to handle select part in
$completedLevels = TableRegistry::get('CompletedLevels');
$completedLevels = $completedLevels->find('All');
$completedLevels = $completedLevels
->contain(['Users', 'Levels'])
->select([
'user_name' => 'Users.name',
'count_questions' => 'COUNT(Questions.id)',
'total_pints' => [
'select'=>'SUM(CompletedLevels.points)'
]
])
->join([
'table' => 'Questions',
'conditions' => 'Questions.level_id = CompletedLevels.level_id',
])
->group(['CompletedLevels.user_id'])
->all();
Found answer
ITS "SUB-Query"
$completedLevels = TableRegistry::get('CompletedLevels');
TableRegistry::config('cl', ['table' => 'completed_levels']);
$cl = TableRegistry::get('cl');
$cl = $cl->find('all');
$cl ->select($cl->func()->sum('points'));
$completedLevels = $completedLevels->find('All');
$completedLevels = $completedLevels
->contain(['Users', 'Levels'])
->select([
'user_name' => 'Users.name',
'count_questions' => 'COUNT(Questions.id)',
'total_pints' => $cl->where('user_id = CompletedLevels.user_id')
])->join([
'table' => 'Questions',
'conditions' => 'Questions.level_id = CompletedLevels.level_id',
])->group(['CompletedLevels.user_id']);

Wp_query post__not_in not working

I'm trying to build a query using wp_query where certain posts id must be excluded. Here is the code that i'm using:
$args = array( 'posttype' => 'post', 'posts_per_page' => 1, 'cat' => 14, 'post__not_in ' => array(71,1), 'orderby' => 'menu_order', 'order' => 'ASC' , 'post_status' => 'publish' );
$the_query = new \WP_Query( $args );
However wp_query is still returning me the posts with those ID's.
Here is the pastebin with the wp_query object http://pastebin.com/gjayN4Yc.
As for the wp_query->request i'm having the following:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (14,15) ) AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.menu_order ASC LIMIT 0, 3
Am i doing something wrong or is this a core bug?
Thank you.
I ran your code and it worked fine for me, except there is an extra space after 'post__not_in '. Do you see it? Make sure you have the key as 'post__not_in'.
Also, there are a couple of things to mention:
It's 'post_type' and not 'posttype.
'menu_order' is not available for posts. That is allocated for hierarchical post types, such as pages. You set that field in the Page Order UI, which is not available (by default) to posts.
Here is the revised code:
$args = array(
'post_type' => 'post',
'posts_per_page' => 1,
'cat' => 14,
'post__not_in' => array( 71, 1 ),
'orderby' => 'date',
'order' => 'ASC',
'post_status' => 'publish',
);
$the_query = new WP_Query( $args );
if ( ! $the_query->have_posts() ) {
// maybe echo a message that none were found
return;
}
while( $the_query->have_posts() ) {
$the_query->the_post();
// do your business logic here
// then call the view file to render the HTML
}
wp_reset_postdata();
The SQL query then becomes:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1 AND wp_posts.ID NOT IN (71,1) AND
( wp_term_relationships.term_taxonomy_id IN (14) ) AND
wp_posts.post_type = 'post' AND
((wp_posts.post_status = 'publish'))
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date ASC LIMIT 0, 1
Have you tried adding a second underscore after post in the $args array key - so it's post__not_in (2 consecutive underscores) rather than post_not_in as per the WP_Query docs?
Try this one
$aTest = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => -1, //all post
'order' => 'ASC',
'cat' => 14,
'post__not_in' => array(27),
'orderby' => 'date',
'post_status' => 'publish'
) );
while ( $aTest ->have_posts() ) : ($aTest ->the_post()) ;
$aTest Image = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
$title = get_the_title();
$content = get_the_content();
endwhile;

CakePHP LEFT JOIN on multiple tables with condition

I want to use this CakePHP form to do a LEFT join. See CakePHP Book - section on Joining Tables
$options['joins'] = array(
array('table' => 'channels',
'alias' => 'Channel',
'type' => 'LEFT',
'conditions' => array(
'Channel.id = Item.channel_id',
)
)
);
$Item->find('all', $options);
EXCEPT that my LEFT JOIN has a dependent table with conditions. In MySQL the join looks like this
LEFT JOIN (
channels as Channel
INNER JOIN regions as Region ON ( Region.id = Channel.region_id and Region.id=1 )
) ON Channel.id = Item.channel_id
Can I do the same thing in CakePHP 2.0 using the $options['joins'] syntax?
So after a bit of fiddling, I discovered this does the "trick" in CakePHP. According to SQL EXPLAIN, this is a much faster join than using a sub-query to force conditions on the LEFT join table
$options['joins'] = array(
array('table' => '(channels as `Channel` INNER JOIN regions as `Region`
ON ( `Region`.id = `Channel`.region_id and `Region`.id=1 ))',
// 'alias' => 'Channel', // the alias is 'included' in the 'table' field
'type' => 'LEFT',
'conditions' => array(
'Channel.id = Item.channel_id',
)
)
);
$Item->find('all', $options);
$options['joins'] = array(
array('table' => 'channels',
'alias' => 'Channel',
'type' => 'LEFT',
'conditions' => array(
'Channel.id = Item.channel_id',
'Region.id' = 1
)
)
);
$Item->find('all', $options);
The condition key in joins options can work too
A bit late but for those who will see this through google like me you should try the following.
$options['joins'] = array(
array(
'table' => 'channels',
'alias' => 'Channel',
'type' => 'LEFT',
'conditions' => array(
'Item.channel_id = Channel.id'
)
),
array(
'table' => 'regions',
'alias' => 'Region',
'type' => 'INNER',
'conditions' => array(
'Channel.region_id = Region.id',
'Region.id = 1'
)
)
);

Select the posts with OR operator in the same meta_key AND operator for differemt meta_key

I have stucked with a mysql query.
I want to select the posts having OR operator between same meta_key then AND operator on different meta_key i have tried :-
SELECT p.ID, p.post_title, pm.meta_value FROM wp_posts p
LEFT JOIN `wp_postmeta` pm ON p.ID =pm.post_id where
((pm.meta_key = 'cost_for_two' AND pm.meta_value IN(".$prices."))
AND (pm.meta_key = 'bar_or_no_bar' AND pm.meta_value='".$bars."') ) LIMIT 0,7
Want to select the post who have bars and prices selected.
as you said "Want to select the post who have bars and prices selected."
You can do this by Wordpress query too.
try this code:
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'cost_for_two',
'value' => $prices,
),
array(
'key' => 'bar_or_no_bar',
'value' => $bars,
)
),
'posts_per_page' => 7
);
$query = new WP_Query( $args );