Yii1 - CActiveDataProvider criteria not working as expected - yii

I am trying to translate this query to CActiveDataProvider:
// SELECT p.id "
// . "FROM projects AS p "
// . "LEFT JOIN purged_files AS pf ON p.id = pf.project_id "
// . "WHERE pf.id IS NULL "
// . "AND `new_status_id` IN ('DELIVERED', 'PAID') "
// . "AND `created` <= '" . date("Y-m-d H:i:s", strtotime("-" . $lifetime_days . " DAYS")) . "' "
// . "ORDER BY id DESC "
// . "LIMIT 0, 5000")
Current code:
$criteria->select = "project.id";
$criteria->join = 'LEFT JOIN purged_files ON project.id = purged_files.project_id';
$criteria->order = "project.id desc";
$criteria->condition = "`new_status_id` IN ('DELIVERED', 'PAID') AND `created` <= '" . date("Y-m-d H:i:s", strtotime("-180 DAYS")) . "'";
$criteria->limit = 5000;
$criteria->offset = 0;
$dataProvider = new CActiveDataProvider('Project', array(
'criteria' => $criteria,
));
$iterator = new CDataProviderIterator($dataProvider);
foreach ($iterator as $project) {
echo $project->id . "<br>";
}
var_dump('<pre>', "end", '</pre>');die;
When I run this I am getting this error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'project.id' in 'on clause'. The SQL statement executed was: SELECT COUNT(*) FROM `projects` `t` LEFT JOIN purged_files ON project.id = purged_files.project_id WHERE (`t`.`status` <> "DELETED" AND `t`.`status` <> "CANCELED" AND `t`.`status` <> "ARCHIVED") AND (`new_status_id` IN ('DELIVERED', 'PAID') AND `created` <= '2017-12-29 13:31:42')
What seems to be the issue here?

You're using incorrect alias in your conditions. Main model table is aliased as t, so either you should use t as alias in your condition instead of project:
$criteria->order = "t.id desc";
Or overwrite alias in criteria:
$criteria->alias = 'project';

Related

Combine SQL Select and AVG in one query

I try to combine a SELECT and an AVG query into one. My query is working but the AVG result is not shown as expected. Error is:
Undefined index
I thought I can combine AVG and SELECT like this?
the result will be a list and should also show an average progress value. If I put this AVG query separately and inside the "fetch" it works but shows only the first result. So it is not a solution for me because I will have much more rows.
I hope someone can help me to rebuild this miracle :)
<?php
$statement = $pdo->prepare("
SELECT
audit.id as audit_id,
audit.uid,
audit.assigned_auditor,
audit.audit_req_comment,
audit.audit_req_date,
audit.audit_date_start,
audit.general_audit_status,
audit.audit_request_date,
audit.audit_type,
audit.audit_date_start,
questionaire.quest_name,
users.nachname,
suppliers.supplier_name,
suppliers.supplier_city,
suppliers.supplier_country,
(SELECT AVG(progress) AS progress FROM answers WHERE relevant = '1' AND audit_id = :audit_id AND rating != required_answer)
FROM audit
JOIN users ON audit.uid = users.id
JOIN suppliers ON audit.supplier_id = suppliers.id
JOIN questionaire ON audit.questionaire_id = questionaire.id
WHERE
audit.cid = :cid
AND audit.general_audit_status = 'Maßnahmenplan'
AND audit.assigned_auditor = :assigned_auditor"
);
$result = $statement->execute(array(':cid' => $cid, ':assigned_auditor' => $user['id'], ':audit_id' => 4));
$count = 1;
while ($row = $statement->fetch()) {
// Datum umwandeln
$original_date = $row['audit_date_start'];
// Creating timestamp from given date
$timestamp = strtotime($original_date);
// Creating new date format from that timestamp
$new_date = date("d.m.Y", $timestamp);
// Audit Typ Namensgebung
if ($row['audit_type'] == "AR") {
$audit_type = "Externes Audit";
}
if ($row['audit_type'] == "RA") {
$audit_type = "Remote Audit";
}
if ($row['audit_type'] == "IA") {
$audit_type = "Internes Audit";
}
if ($row['audit_type'] == "SAA") {
$audit_type = "Self Assessment Audit";
}
//Berechne die durchschnittliche Abarbeitung aller Maßnahmen dieses Audits
//$statement = $pdo->prepare("SELECT AVG(progress) AS progress FROM answers WHERE relevant = '1' AND audit_id = :audit_id AND rating != required_answer");
//$statement->execute(array(':audit_id' => $row['audit_id']));
//$total_progress = $statement->fetch();
echo "<tr>";
echo "<td>" . $row['audit_id'] . "</td>";
echo "<td>" . $new_date . "</td>";
echo "<td>" . $row['supplier_name'] . "</td>";
echo "<td>" . $row['supplier_city'] . " (" . $row['supplier_country'] . ")</td>";
echo "<td>" . $row['quest_name'] . "</td>";
echo "<td>" . $audit_type . "</td>";
echo "<td>" . round($row['progress'], 0) . " %</td>";
echo '<td align="center"><i class="fas fa-edit"></i></td>';
echo "</tr>";
}
?>
As I understand your question, you just need to alias the results of the subquery in the outer query (rather than in the inner query itself):
SELECT
audit.id as audit_id,
audit.uid,
audit.assigned_auditor,
audit.audit_req_comment,
audit.audit_req_date,
audit.audit_date_start,
audit.general_audit_status,
audit.audit_request_date,
audit.audit_type,
audit.audit_date_start,
questionaire.quest_name,
users.nachname,
suppliers.supplier_name,
suppliers.supplier_city,
suppliers.supplier_country,
(
SELECT AVG(progress)
FROM answers
WHERE relevant = 1 AND audit_id = :audit_id AND rating != required_answer
) AS progress --> here
FROM audit
JOIN users ON audit.uid = users.id
JOIN suppliers ON audit.supplier_id = suppliers.id
JOIN questionaire ON audit.questionaire_id = questionaire.id
WHERE
audit.cid = :cid
AND audit.general_audit_status = 'Maßnahmenplan'
AND audit.assigned_auditor = :assigned_auditor"

WPDB query what is the cleanest method for a double query?

I am curious as to how best achieve this.
wpdb query 1:
$results = $wpdb->get_results(
"SELECT *
FROM $table_name
WHERE user_id = '$userid';"
);
I then want to do another wpdb query on a separate table using $results->post_id in the WHERE part of the query such as:
$results2 = $wpdb->get_results(
"SELECT *
FROM $table_name2
WHERE user_id = '$results->post_id' && type = '$type';"
);
I am conscious that $results will be an array so I don't think the above will work directly and some sort of compound "for each" seems cumbersome.
What are my options please?
Update example based on Jarlh's comment
$userid = get_current_user_id();
global $wpdb;
$table_name = $wpdb->prefix . 'postmeta';
$table2_name = $wpdb->prefix . 'posts';
$rewards_results = $wpdb->get_results(
"SELECT *
FROM $table_name
WHERE post_id in ("SELECT user_id
FROM $table2_name
WHERE user_id = '$userid';")"
);
Update 2:
$userid = get_current_user_id();
global $wpdb;
$table_name = $wpdb->prefix . 'postmeta';
$table2_name = $wpdb->prefix . 'posts';
$results = $wpdb->get_results(
"SELECT *
FROM $table_name
WHERE ID in (SELECT user_id
FROM $table2_name
WHERE user_id = '$userid')"
);
//return $results;
foreach ($results as $row) {
echo "<td class='dash-2-td'>" . esc_html($row->logo_id) . "</td>";
echo "<td class='dash-2-td'>" . esc_html($row->belongs_to) . "</td>";
echo "</tr>";
}
This is producing no output.
I need to search $table_name->post_id for rows that match $table2_name->ID where user_id = $userid
Update 3: print_r is just showing array(), seems empty
$userid = get_current_user_id();
global $wpdb;
//$table_name = $wpdb->prefix . 'postmeta';
//$table2_name = $wpdb->prefix . 'posts';
$results = $wpdb->get_results(
"SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->posts.post_author = $userid
AND $wpdb->postmeta.plan = 3981
");
return $results;
I ended up using wp_query which I had not even considered as an option.
As a solution, you can use INNER JOIN. Also, I'd suggest you to use $wpdb->prepare for escaping values. Here is an example:
$sql = $wpdb->prepare( "SELECT a.*, b.col1, b.col2 FROM $table1 as a INNER JOIN $table2 as b ON a.user_id = b.user_id WHERE a.user_id = %d AND b.type = %s", $user_id, $type );
$entries = $wpdb->get_results( $sql, ARRAY_A );
Hope it helps.

How to get data between two field in codeigniter

i have a field in table like this,
i have a code like this,
public function get_data_promocode($db) {
$date = date('Y-m-d H:i:s');
$this->db->from($db);
$this->db->where('promo_start >=', date('Y-m-d 00:00:00',strtotime($date)));
$this->db->where('promo_end <=', date('Y-m-d 23:59:59',strtotime($date)));
$this->db->where('promo_count IS NULL', null, false);
$this->db->order_by('promo_id DESC');
$query = $this->db->get();
return $query->result();
}
how to display promo data that is still on when the current date is between promo_start and promo_end?
get your promo_start_date and promo_end_date and pass those variables with your method
$this->db->where("promo_end >= '" . $promo_start_date . "' AND promo_start <= '" . $promo_end_date . "'")

same table same field with same field conditions - Possible? in one sql

here is my query i want to execute it as
$query="select * from $post INNER JOIN $postmeta on $postmeta.post_id= $post.ID
where $post .post_status='publish'
and $post .post_type ='task
and $post .post_type='service'
ORDER BY $post .post_date DESC ";
how to execute
Previous a proper sanitize of the var $postmeta and $post you can do this way
Building dinamic query by string concantenation (because var in tabel and column name are not allowed in sql)
$query="select * from " . $post . " INNER JOIN " .
$postmeta . " on " . $postmeta . ".post_id= " . $post .".ID where " .
$post . ".post_status='publish' and " . $post .".post_type ='task' and " .
$post . "post_type='service' ORDER BY " . $post .".post_date DESC ";

wpdb select query to get certain meta_key?

I have the below code where I am trying to get a list of orders.
So from the wcomm (woocommerce_order_itemmeta) table, I only want to display the meta_value where the meta_key is equal to _qty or _product_id and I need the _product_id to be filtered on a single value like I have. I can't seem to make it only do both things.. My output never shows the _qty value because I'm specifically filtering the value of _product_id but I don't understand what to change
global $wpdb;
$wpdb->woocommerce_order_items = $wpdb->prefix . 'woocommerce_order_items';
$wpdb->woocommerce_order_itemmeta = $wpdb->prefix . 'woocommerce_order_itemmeta';
$uvuorderposts = $wpdb->get_results(
"
SELECT p.ID, p.post_title, p.post_date, wcom.order_item_name, wcomm.meta_key, wcomm.meta_value
FROM $wpdb->posts AS p
INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
INNER JOIN $wpdb->woocommerce_order_items AS wcom ON p.ID = wcom.order_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm ON wcom.order_item_id = wcomm.order_item_id
WHERE (p.post_type = 'shop_order')
AND (pm.meta_key = '_wc_authorize_net_aim_charge_captured')
AND (pm.meta_value = 'yes')
AND (wcomm.meta_key = '_product_id')
OR (wcomm.meta_key = '_qty')
AND (wcomm.meta_value = '2193')
ORDER BY p.post_date
"
);
echo "<table>";
foreach ( $uvuorderposts as $uvuorderpost )
{
echo "<tr><td>" . $uvuorderpost->post_title . " - " . $uvuorderpost->ID . "</td><td>" . $uvuorderpost->post_date . "</td><td>" . $uvuorderpost->meta_key . ": " . $uvuorderpost->meta_value . "</td></tr>";
echo "<tr bgcolor='#eaeaea'><td colspan='3'>" . $uvuorderpost->order_item_name . "</td></tr>";
}
echo "</table>";
I tried to "filter" it on the output by using $uvuorderpost->meta_key['_qty'] but it did not work!
I fixed it with the following changes. Just joined that table twice and it works now. Not sure if it's best practice but yeah
global $wpdb;
$wpdb->woocommerce_order_items = $wpdb->prefix . 'woocommerce_order_items';
$wpdb->woocommerce_order_itemmeta = $wpdb->prefix . 'woocommerce_order_itemmeta';
$uvuorderposts = $wpdb->get_results(
"
SELECT p.ID, p.post_title, p.post_date, wcom.order_item_name, wcomm.meta_key, wcomm.meta_value, wcomm2.meta_key AS meta_key_qty, wcomm2.meta_value AS meta_value_qty
FROM $wpdb->posts AS p
INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
INNER JOIN $wpdb->woocommerce_order_items AS wcom ON p.ID = wcom.order_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm ON wcom.order_item_id = wcomm.order_item_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm2 ON wcom.order_item_id = wcomm2.order_item_id
WHERE (p.post_type = 'shop_order')
AND (pm.meta_key = '_wc_authorize_net_aim_charge_captured')
AND (pm.meta_value = 'yes')
AND (wcomm.meta_key = '_product_id')
AND (wcomm.meta_value = '2193')
AND (wcomm2.meta_key = '_qty')
ORDER BY p.post_date
"
);
echo "<table>";
foreach ( $uvuorderposts as $uvuorderpost )
{
echo "<tr><td>" . $uvuorderpost->post_title . " - " . $uvuorderpost->ID . "</td><td>" . $uvuorderpost->post_date . "</td></tr>";
echo "<tr bgcolor='#eaeaea'><td colspan='2'>" . $uvuorderpost->order_item_name . "</td></tr>";
echo "<tr bgcolor='#eaeaea'><td colspan='2'>" . $uvuorderpost->meta_key . " : " . $uvuorderpost->meta_value . "</td></tr>";
echo "<tr bgcolor='#eaeaea'><td colspan='2'>" . $uvuorderpost->meta_key_qty . " : " . $uvuorderpost->meta_value_qty . "</td></tr>";
}
echo "</table>";