How to search two meta values from same single column and table - php

I make a custom search in WordPress. There are three fields for searching.
Age
Location
Post Title
Post Title is searched from wp_posts > post_title field and location and age are custom meta fields y_age, y_activity_locations. So there is 6 scenarios of searching.
If user enter:
Enter Title or
Select Location or
Select Age or
Enter Title and Select Location or
Enter Title and Select Age or
Select Location and Select Age
My first 5 (Five) scenarios are working perfectly but my 6th scenario is not working because it comes from same table (wp_postmeta) and same column but two different values.
So I tried this query:
Select y_posts.*, y_meta.*
From wp_posts As y_posts
Inner Join wp_postmeta As y_meta
On y_posts.ID = y_meta.post_id
Where y_posts.post_type = 'download'
And y_posts.post_status = 'publish'
And y_meta.meta_key = 'y_activity_locations'
And y_meta.meta_value Like '%Armidale%'
And y_meta.meta_key = 'y_age'
And y_meta.meta_value Like '%3 to 5%'
The query is not working because I think sever confused two values from same column.
Select y_posts.*, y_meta.*
From wp_posts As y_posts
Inner Join wp_postmeta As y_meta
On y_posts.ID = y_meta.post_id
Where y_posts.post_type = 'download'
And y_posts.post_status = 'publish'
And y_meta.meta_key = 'y_activity_locations'
And y_meta.meta_value Like '%Armidale%'
Or y_meta.meta_key = 'y_age'
Or y_meta.meta_value Like '%3 to 5%'
This query works and it gives me only age or location data but i want search both values at a same time.
I also tried sub query (Never tried before)
Select y_posts.*, y_meta.*
From wp_posts As y_posts
Inner Join wp_postmeta As y_meta
On y_posts.ID = y_meta.post_id
Where y_posts.post_type = 'download'
And y_posts.post_status = 'publish'
And y_meta.meta_key = 'y_activity_locations'
And y_meta.meta_value Like '%Armidale%'
And (Select yy_meta.* From wp_postmeta As yy_meta Where yy_meta.meta_key = 'y_age'
And yy_meta.meta_value Like '%3 to 5%')
But it gives me this error
1241 - Operand should contain 1 column(s)
So please guide me how can I get two values from same column.
Please give me only query suggestions not any other solutions.

Please try following query :
Select y_posts.*, y_meta.*
From wp_posts As y_posts
Inner Join wp_postmeta As y_meta
On y_posts.ID = y_meta.post_id
Where y_posts.post_type = 'download'
And y_posts.post_status = 'publish'
And (
(y_meta.meta_key = 'y_activity_locations'
And y_meta.meta_value Like '%Armidale%')
Or (y_meta.meta_key = 'y_age'
And y_meta.meta_value Like '%3 to 5%')
)

You try, wordpress query
<?php
$argsCat = array(
'posts_per_page' => -1,
'post_type' => 'download',
'meta_key' => 'y_activity_locations',
'meta_value' => '%Armidale%',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'y_age',
'value' => '3',
'compare' => '>='
),
'relation' => 'AND',
array(
'key' => 'y_age',
'value' => '5',
'compare' => '<='
)
),
);
$normal_array = get_posts($argsCat);
?>

Related

COUNT function in sql counting whole data in database

I am trying to count the number of data in the database according to the category id and I have written the following lines of code:
public function getPodcastByCategoryId($catId){
$args = array(
'fields' => array(
'podcast.id',
'podcast.title',
'podcast.description',
'podcast.duration',
'podcast.audio',
'podcast.image',
'podcast.category',
'podcast.added_date',
'categories.title AS category_title',
'(SELECT users.full_name FROM users WHERE id = podcast.added_by) as author',
'(SELECT COUNT(category) FROM podcast WHERE category = podcast.category) as episodes'
),
'join' => "LEFT JOIN categories on podcast.category = categories.id",
'where' => array(
'category' => $catId
),
);
return $this->select($args);
}
However, the function getPodcastByCategoryId($catId) is giving episodes = 3 which is the count of data present in table podcast.
Data in database:
My expected episodes would be 2 in category id 2 and 1 in category id 1.
for episode you should use COUNT(*)
$args = array(
'fields' => array(
'podcast.id',
'podcast.title',
'podcast.description',
'podcast.duration',
'podcast.audio',
'podcast.image',
'podcast.category',
'podcast.added_date',
'categories.title AS category_title',
'(SELECT users.full_name FROM users WHERE id = podcast.added_by) as author',
'(SELECT COUNT(*) FROM podcast WHERE categories.category = podcast.category) as episodes'
),
'join' => "LEFT JOIN categories on podcast.category = categories.id",
'where' => array(
'category' => $catId
),
);

CakePHP 3.6: Count distinct records from table

I am trying to achieve a distinct count on a table with a where condition.
This is what I have tried:
$customerServiceTypes = TableRegistry::get('CustomerServiceTypes');
$customers_count = $customerServiceTypes->find('all', array(
'fields' => 'DISTINCT CustomerServiceType.customer_id',
'conditions' => array("CustomerServiceTypes.service_type_id" => $id)))->count();
But its not working. I get 25 as result but it should be 2. Distinct is not working.
$customerServiceTypes = TableRegistry::get('CustomerServiceTypes');
$customers_count = $customerServiceTypes->find()
->select(['customer_id'])
->distinct()
->where(['service_type_id =' => $id])->count();

data escaping remove for specific filed in cakephp

I am using subquery for id field.
$db = $this->AccountRequest->getDataSource();
$subQuery = $db->buildStatement(
array(
'fields' => array('MAX(id)'),
'table' => $db->fullTableName($this->AccountRequest),
'alias' => 'MaxRecord',
'limit' => null,
'offset' => null,
'order' => null,
'group' => array("user_id")
),
$this->AccountRequest
);
$searching_parameters = array(
#"AccountRequest.id IN " => "(SELECT MAX( id ) FROM `account_requests` GROUP BY user_id)"
"AccountRequest.id IN " => "(".$subQuery.")"
);
$this->Paginator->settings = array(
#'fields' => array('AccountRequest.*'),
'conditions' => $searching_parameters,
'limit' => $limit,
'page' => $page_number,
#'group' => array("AccountRequest.user_id"),
'order' => array(
'AccountRequest.id' => 'DESC'
)
);
$data = $this->Paginator->paginate('AccountRequest');
This structure is producing a query is:
SELECT
`AccountRequest`.`id`,
`AccountRequest`.`user_id`,
`AccountRequest`.`email`,
`AccountRequest`.`emailchange`,
`AccountRequest`.`email_previously_changed`,
`AccountRequest`.`first_name`,
`AccountRequest`.`first_namechange`,
`AccountRequest`.`f_name_previously_changed`,
`AccountRequest`.`last_name`,
`AccountRequest`.`last_namechange`,
`AccountRequest`.`l_name_previously_changed`,
`AccountRequest`.`reason`,
`AccountRequest`.`status`,
`AccountRequest`.`created`,
`AccountRequest`.`modified`
FROM
`syonserv_meetauto`.`account_requests` AS `AccountRequest`
WHERE
`AccountRequest`.`id` IN '(SELECT MAX(id) FROM `syonserv_meetauto`.`account_requests` AS `MaxRecord` WHERE 1 = 1 GROUP BY user_id)'
ORDER BY
`AccountRequest`.`id` DESC
LIMIT 25
In the subquery, its add an extra single quote so it's producing an error.
So, How can I remove these single quotes from this subquery?
Thanks
What are you trying to achieve with the sub query?
The MAX(id) just means it will pull the id with the largest value AKA the most recent insert. The sub query is completely redundant when you can just ORDER BY id DESC.
using MAX() will return only one record, if this is what you want to achieve you can replicate by adding LIMIT 1
If the sub query is just an example and is meant to be from another table I would just run the query that gets the most recent id before running the main query. Getting the last inserted id in a separate query is very quick and I cant see much of a performance loss. I think it will result in cleaner code that`s easier to follow to.
edit 1: From the comments it sounds like all your trying to get is a particular users latest account_requests.
You dont need the sub query at all. My query below will get the most recent account record for the user id you choose.
$this->Paginator->settings = array(
'fields' => array('AccountRequest.*'),
'conditions' => array(
'AccountRequest.user_id' => $userID // you need to set the $userID
)
'page' => $page_number,
'order' => array(
'AccountRequest.id DESC' //shows most recent first
),
'limit' => 1 // set however many you want the maximum to be
);
The other thing you cold be meaning is to get multiple entries from multiple users and display them in order of user first and then the order of recent to old for that user. MYSQL lets you order by more than one field, in that case try:
$this->Paginator->settings = array(
'conditions' => array(
'AccountRequest.user_id' => $userID // you need to set the $userID
)
'page' => $page_number,
'order' => array(
'AccountRequest.user_id', //order by the users first
'AccountRequest.id DESC' //then order there requests by recent to old
)
);
If the example data you have added into the question is irrelevant and you are only concerned about how to do nested subqueries it has already been answered here
CakePHP nesting two select queries
However I still think based on the data in the question you can avoid using a nested query.

How to get data from different associated tables using containable in Cakephp?

I have 3 tables: orders, discounts and products in the way that product has many discounts (discount times). Discount has many orders. in other words, it looks like: Product > Discount > Order.
I want to get data from 3 tables as the raw mySQL query below:
SELECT discounts.product_id, products.product_name,
sum(products.product_price - discounts.product_discount) as total_Amount,
count(orders.order_id) as total_Number
FROM products
inner join discounts on products.product_id = discounts.product_id
inner join orders on discounts.discount_id = orders.discount_id
group by discounts.product_id,products.product_name
This is what I did:
$this->Order->virtualFields['benefit']='SUM(Product.product_price - Discount.product_discount)';
$this->Order->virtualFields['number']='COUNT(Order.order_id)';
$products = $this->Order->find('all',array('contain'=>array('Discount'=>array('Product'))),
array( 'limit'=>20,
'fields'=>array('benefit','number'),
'group'=>array('Discount.product_id','Product.product_name')));
Debugger::dump($products);
$this->set('products',$products);
But I got an error:
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Product.product_price' in 'field list'
SQL Query: SELECT `Order`.`order_id`, `Order`.`user_id`
`Order`.`order_date`, `Order`.`payment`, `Order`.`discount_id`, `Order`.`total`,
(SUM(`Product`.`product_price` - `Discount`.`product_discount`)) AS `Order__benefit`,
(COUNT(`Order`.`order_id`)) AS `Order__number`, `Discount`.`discount_id`,
`Discount`.`product_id`, `Discount`.`product_discount`,
`Discount`.`start_time`, `Discount`.`end_time`
FROM `project`.`orders` AS `Order`
LEFT JOIN `project`.`discounts` AS `Discount`
ON (`Order`.`discount_id` = `Discount`.`discount_id`) WHERE 1 = 1
It seems that containable didnt work as it didnt not contain products table in the query.
EDIT: according to Dave's suggestion, I used JOIN:
$this->Order->recursive=-1;
$this->Order->virtualFields['benefit']='SUM(Product.product_price - Discount.product_discount)';
$this->Order->virtualFields['number']='COUNT(Order.order_id)';
$option['joins'] = array(
array('table'=>'discounts',
'alias'=>'Discount',
'type'=>'INNER',
'conditions'=>array(
'Order.discount_id = Discount.discount_id',
)
),
array('table'=>'products',
'alias'=>'Product',
'type'=>'INNER',
'conditions'=>array(
'Discount.product_id = Product.product_id'
)
)
);
$products = $this->Order->find('all',$option,
array( 'limit'=>20,
'fields'=>array('Discount.product_id','Product.product_name'),
'group'=>array('Discount.product_id','Product.product_name')));
Debugger::dump($products);
$this->set('products',$products);
However, what $products contains is only:
array(
(int) 0 => array(
'Order' => array(
'order_id' => '23567636',
'user_id' => '1',
'order_date' => '2013-11-16 16:03:00',
'payment' => 'mc',
'discount_id' => '2',
'total' => '599',
'benefit' => '7212',
'number' => '19'
)
)
)
but, what I want is:
How can I fix that? thanks in advance.
Containable is not the same as JOIN.
Containable does not join the queries into a single query, but for the most part creates completely separate queries, then combines the results for your viewing pleasure.
So - per your error, in the query that's being run on the orders table, there IS no Product.product_price field because those fields are available only in a completely separate query.
Try using JOINs instead.

Cakephp using group by in find method

I'm trying to use Group by in find method for my relational database I want to get the latest record with unique receiver_id out of result set filtered by user_id and below is my code:
$this->loadModel('Chat');
$lastChat = $this->Chat->find('all', array(
'conditions' => array(
'Chat.user_id' => $user_id['User']['id']
),
'fields' => array(
'Chat.id',
'Chat.chat',
'Chat.user_id',
'Chat.receiver_id',
'Chat.read',
'Chat.created'
),
'group' => array('Chat.receiver_id'),
'order' => array('Chat.created DESC')
));
However, this does not seem to work. I'm not sure why but I'm only getting one result...
How can I get multiple results with rules based on above.
Try the following:
$db = $this->Chat->getDataSource();
$chats = $db->query("SELECT * , (Chat.user_id + Chat.receiver_id) AS dist
FROM (
SELECT *
FROM chats t
WHERE ( t.user_id =$id OR t.receiver_id =$id )
ORDER BY t.id DESC
) Chat
GROUP BY dist
ORDER BY Chat.id DESC");

Categories