I am using WordPress platform, and using WP_Query to call my data although can use custom MYSQL script if if can work.
I just want to add a where condition which can filter JSON value as below explained:
so in postmeta table i have a following columns
meta_key: _stock_reserve_outlet_extended
meta_value: a:2:{s:8:"outlet_2";a:2:{s:5:"stock";s:2:"20";s:5:"rider";s:2:"-1";}s:8:"outlet_1";a:2:{s:5:"stock";i:-4;s:5:"rider";i:0;}}
which is actually an array extracted as below by get_post_meta() function:
Array (
[outlet_2] => Array (
[stock] => 45
[rider] => 0
)
[outlet_1] => Array (
[stock] => -4
[rider] => 0)
)
)
i want to filter rows during calling rows from script by comparing following:
stock > 0 in outlet_2
I tried to search filter json values filtration by json_search but that does not compare by key.
To give WP_Query a try, i use following but nothing effect shows
$args['meta_query'][] = array(
'key' => '_stock_outlet_extended',
'value' => array(
'key' => 'stock',
'value' => '18'
),
'compare' => '>',
);
Then i tried following script but that not work aswell:
SELECT meta_value
FROM `frbl1ozme_postmeta`
WHERE `post_id` = 3699 AND `meta_key` = '_stock_outlet_extended' AND meta_value ->'$.stock' > 1;
Do anyone know how to tackle this sort of criteria?
what i observer is if you are saving any array by using update_post_meta() function of wordpress then it will serialize it and you are unable to filter rows by script then.
So after understood this fact i made the changes in structure and along with the stock i am saving status according to the value condition of stock, so i can filter rows easily by MYSQL.
So in one line answer, one can not achieve filter serialize rows via mysql queries till date.
Thank you all for the Help, specially #RiggsFolly
Related
So I have a model FeaturedListing that has a field date which is a mysql date field. There will be multiple FeaturedListings that have the same date value.
I want to find all dates that have N or more FeaturedListings on it. I think I'd have to group by date and then find which ones have N or more in there group and get the value that was grouped on. Could any one give me any pointers to accomplish that. A raw sql query may be required.
Edit: Thanks to the answers below it got me going on the right track and I finally have a solution I like. This has some extra conditions specific to my application but I think its pretty clear. This snippet finds all dates after today that have at least N featured listings on them.
$dates = $this->find('list', array(
'fields' => array('FeaturedListing.date'),
'conditions' => array('FeaturedListing.date >' => date('Y-m-d') ),
'group' => array('FeaturedListing.date HAVING COUNT(*) >= $N')
)
);
I then make a call to array_values() to remove the index from the returned list and flatten it to an array of date strings.
$dates = array_values($dates);
No need to go to raw SQL, you can achieve this easily in cake ($n is the variable that holds N):
$featuredListings = $this->FeaturedListing->find('all', array(
'fields' => array('FeaturedListing.date'),
'group' => array('FeaturedListing.date HAVING COUNT(*)' => $n),
));
In "raw" SQL you would use group by and having:
select `date`
from FeaturedListings fl
group by `date`
having count(*) >= N;
If you want the listings on these dates, you need to join this back to the original data. Here is one method:
select fl.*
from FeaturedListings fl join
(select `date`
from FeaturedListings fl
group by `date`
having count(*) >= N
) fld
on fl.`date` = fld.`date`
How could I create a sub-query in cakePHP with find method? For example:
SELECT *, (SELECT COUNT(*) FROM table2 WHERE table2.field1 = table1.id) AS count
FROM table1
WHERE table1.field1 = 'value'
!!! table2.field1 = table1.id !!!
Just for addition, you can build subquery using Cake's ORM. It will be more easy. Please read CakePHP retrieving data doc
In general you can use buildStatement() method of DataSource object. You can save all logic, including pagination etc.
You can do this one of two ways:
1. Use $this->Model->query(...)
This allows you execute SQL directly using the query you posted above but be aware that it can make your application quite brittle if the database schema were to change. Probably the fastest.(Documentation)
Example
$this->Model1->query("SELECT * FROM model;");
2. Separate the Calls
This is probably not as fast as option 1 but it does give you the ability to break your query down into a number of steps. You're also unlikely to get SQL injection which is potential risk with option 1.
Example
$model1s = $this->Model1->find
(
'all',
array
(
'conditions' => array('Model1.field1' => 'value')
)
);
foreach($model1s as $model1)
{
$model1['model2_count'] = $this->Model2->find
(
'count',
array
(
'conditions' => array
(
'Model2.field1' => $model1['id']
)
)
);
}
I have 2 database tables
JOBS(JOB_ID, JOB_TIME, JOB_NAME,...), JOB_PARAMETERS(JOB_ID,NAME,VALUE)
where JOB_PARAMETERS is essentially a map containing job parameter key value pairs.
Every job may have a unique parameter key/value pairs.
I am looking to pragmatically build a query that will return distinct job id's that contain key/value combinations. Where the values are actually a list of values, comparison operators.
For example:
JOB_PARAMETERS: NAME = 'OUTPUT_FILENAME', VALUE LIKE "ALEX%", "JAX%"
NAME = 'PRIORITY' , VALUE > 7
The above example would automatically filter out all jobs that don't have the OUTPUT_FILENAME and PRIORITY key. Returning All jobs that meet both conditions.
I also need to be able to support pagination and order by.
I was planning on using Perl with DBIx::Class, But I can do it in pure Perl/SQL as well.
I am open to changing the database schema, but every job can have different key/value pairs, so I cant just make them columns in the jobs table.
Thanks in advance.
When using DBIx::Class you can generate a DBIC schema by using Schema::Loader.
After connecting to the database you get a $schema object you can use to get a ResultSet filtered to return the Result objects you want:
my $rs_job_parameters = $schema->resultset('Job_Parameters')->search({
-or => [
{
'name' => 'OUTPUT_FILENAME',
'value' => [{ like => 'ALEX%'}, { like => 'JAX%' }].
},
{
'name' => 'PRIORITY',
'value' => [{ '>' => 7}].
}
]},
{
columns => [qw( job_id )],
group_by => [qw( job_id )], # alternative you can use distinct => 1 to group_by all selected columns
having => \[ 'COUNT(*) = ?', [ 2 ] ],
}
);
my #job_ids = $rs_job_parameters->get_column('job_id')->all;
One can do it in SQL, by grouping JOB_PARAMETERS by JOB_ID and filtering the groups accordingly. For example, if there is a uniqueness constraint over (JOB_ID, NAME), one can query as follows:
SELECT JOB_ID
FROM JOB_PARAMETERS
WHERE (NAME='OUTPUT_FILENAME' AND (VALUE LIKE 'ALEX%' OR VALUE LIKE 'JAX%'))
OR (NAME='PRIORITY' AND VALUE > 7)
GROUP BY JOB_ID
HAVING COUNT(*) = 2
Absent such a uniqueness constraint, COUNT(*) would have to be replaced e.g. with COUNT(DISTINCT NAME).
I have wp_users table which has a column ordering. I came to know that get_users() returns all the users.
I am using it like get_users('orderby=ordering')
I got help form this link
But unfortunately it is not sorting on ordering column.
Any help?
You should first take a look at the users table from the database.
The command you try is good, but the argument you use for ordering might be wrong. You should order by a column from the users table, for example user name, or user id's..
On the link you mentioned I've found these:
orderby - Sort by 'ID', 'login', 'nicename', 'email', 'url', 'registered', 'display_name', or 'post_count'.
order - ASC (ascending) or DESC (descending).
Some working examples:
Get users by nicename:
$users = get_users('orderby=nicename');
Other examples:
Display users sorted by Post Count, Descending order
$user_query = new WP_User_Query( array ( 'orderby' => 'post_count', 'order' => 'DESC' ) );
Display users sorted by registered, Ascending order
$user_query = new WP_User_Query( array ( 'orderby' => 'registered', 'order' => 'ASC' ) );
I have a MySQL table with 3 columns (thread_id, message_id, message). Along the lines of the solution found under the "Example using GROUP BY" in this link, I want my query to GROUP BY thread_id, but return the line of of the highest message_id (instead of default lowest) for each thread_id. I then want a nicely formatted array with lines/items just like you get for less complex find operations in CakePHP along the lines of $array[index]['Model']['field']. Using the following CakePHP syntax:
$this->Model->find('all', array(
'fields' => array('MAX(Model.message_id) as message_id', 'Model.thread_id', 'Model.message'),
'group => 'Model.thread_id'
));
Now, unfortunately I am not getting that nicely formatted array. Instead I get an array which looks something like:
Array ( [0] => Array ( [0] => Array ( [message_id] => wanted/correct_message_id ) [Model] => Array ( [message] => Message from lowest/unwanted message_id line. [thread_id] => Key from lowest/unwanted message_id line))
Why does the message_id not get hooked onto the [Model] part of the array and why does CakePHP fetch the lowest message_id line and put the message and thread_id into the [Model] part of the array without the message_id column?
I want all thre columns in the [Model] part of the array and I want that line to be the highest message_id for that thread_id per my initial description. Hope this question makes sense.
Virtual fields are really useful for this kind of thing.
class MyModel extends AppModel {
public $virtualFields = array(
'max_message_id' => 'MAX(MyModel.message_id)'
);
}
You can now use max_message_id as if it were a normal field in your table, so you can add it to your find operations.