Wordpress select for multiple meta_keys? - wordpress

I can do this.
mysql> select * from wp_postmeta where post_id = '1304090';
+---------+---------+-------------------+--------------+
| meta_id | post_id | meta_key | meta_value |
+---------+---------+-------------------+--------------+
| 4965987 | 1304090 | mp_tax_inclusive | 3 |
| 4965988 | 1304090 | mp_tax_shipping | 5 |
| 4965989 | 1304090 | mp_order_items | 1 |
| 4965985 | 1304090 | mp_shipping_tax | 0 |
+---------+---------+-------------------+--------------+
I now want to find all post_id's where meta_key "mp_tax_shipping" = 5 AND meta_key "mp_tax_inclusive" = 3. How can I specify both? I can specify one with:
select * from wp_postmeta where meta_key = 'mp_tax_shipping' and meta_value = '5'
but I need both criteria met. thanks.

SELECT
pm.post_id
FROM
wp_postmeta AS pm
INNER JOIN
wp_postmeta AS pm2 ON pm2.post_id = pm.post_id
WHERE pm.meta_key = 'mp_tax_shipping' AND pm.meta_value = '5' AND
pm2.meta_key = 'mp_tax_inclusive' AND pm2.meta_value = '3'

Related

Simple mysql SELECT with IN-clause (which returns an empty set) runs forever

On my MariaDB I have a table, 'cv_attribute', which contains 296k records and has 8 columns:
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| cvId | varchar(255) | NO | MUL | NULL | |
| updateId | bigint(20) | NO | MUL | NULL | |
| attributeId | varchar(255) | YES | | NULL | |
| attributeType | varchar(255) | YES | | NULL | |
| attributeLang | varchar(255) | YES | | NULL | |
| attributeValue | varchar(255) | YES | | NULL | |
| MD5 | varchar(255) | YES | MUL | NULL | |
| ingestId | bigint(20) | YES | | NULL | |
+----------------+--------------+------+-----+---------+-------+
I was given a script that runs the query
SELECT DISTINCT * FROM cv_attribute WHERE `MD5` IN (SELECT `MD5` FROM cv_attribute GROUP BY `MD5` HAVING COUNT(*) > 1);
but this runs forever. As in: still running even after a week!
Notice that the query contains an IN-clause. When running the query within that IN-clause, it takes 11 seconds and returns no results:
SELECT `MD5` FROM cv_attribute GROUP BY `MD5` HAVING COUNT(*) > 1;
Empty set (11.51 sec)
I'm totally clueless how the complete query (which basically is just a SELECT DISTINCT *) never finishes, while it's IN-clause returns an empty set within 11 seconds. So, to my understanding, this SELECT DISTINCT * would just query an empty list and be pretty fast.
Note, this is the explain of the full query:
explain SELECT DISTINCT * FROM cv_attribute WHERE `MD5` IN (SELECT `MD5` FROM cv_attribute GROUP BY `MD5` HAVING COUNT(*) > 1);
+------+--------------------+--------------+------+---------------+------+---------+------+--------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+--------------+------+---------------+------+---------+------+--------+------------------------------+
| 1 | PRIMARY | cv_attribute | ALL | NULL | NULL | NULL | NULL | 505223 | Using where; Using temporary |
| 2 | DEPENDENT SUBQUERY | cv_attribute | ALL | NULL | NULL | NULL | NULL | 505223 | Using temporary |
+------+--------------------+--------------+------+---------------+------+---------+------+--------+------------------------------+
2 rows in set (0.00 sec)
I hope anybody here would see the light!
Thanks a lot!
Carl

SQLite UPDATE Value Using Foreign Key Reference

Given three tables with one table serving as a junction table which contains two foreign key columns, I'm trying to make an insert so that, given a TableA.prefix, TableA.number, TableB.prefix, and TableB.number, I can update the JunctionTable.is_archived column for the matching row in JunctionTable:
So while the matching row in JunctionTable currently looks like:
+----------------------------------------------------------------------+
| id | tblA_id | tblB_id | is_archived |
| 3 | 7 | 98 | 0 |
+----------------------------------------------------------------------+
And matching rows in TableA and TableB look like:
TableA
+----------------------------------------------+
| id | prefix | number |
| 7 | CLA | 754 |
+----------------------------------------------+
TableB
+----------------------------------------------+
| id | prefix | number |
| 98 | RED | 221 |
+----------------------------------------------+
I'd like to UPDATE the is_archived value like so:
+----------------------------------------------------------------------+
| id | tblA_id | tblB_id | is_archived |
| 3 | 7 | 98 | 1 |
+----------------------------------------------------------------------+
I've tried a few different statements based on information found here but they aren't valid:
UPDATE JunctionTable
SET is_archived = "1"
WHERE tblAid =
(SELECT id FROM TableA WHERE prefix = "CLA" AND number = 754)
AND tblB.id =
(SELECT id FROM TableB WHERE prefix = "RED" AND number = 221)
UPDATE JunctionTable
SET is_archived = "1"
WHERE (
LEFT JOIN TableA ON JunctionTable.tblA_id=TableA.id
WHERE TableA.course_prefix = "CLA" AND TableA.course_number = 754
LEFT JOIN TableB ON JunctionTable.tblB_id=TableB.id
WHERE TableB.course_prefix = "RED" AND TableB.course_number = 221)
In the first query, it looks like the problems are the names of the ID columns in your Junction table ("tblAid" and "tblB.id"), and you're using double quotes instead of single quotes. This should work:
UPDATE JunctionTable
SET is_archived = 1
WHERE tblA_id =
(SELECT id FROM TableA WHERE prefix = 'CLA' AND number = 754)
AND tblB_id =
(SELECT id FROM TableB WHERE prefix = 'RED' AND number = 221)

Doctrine many to many left join

I have a problem with creating a query which should return cost centers not assigned to budget.
Database structure:
**Cost_center:**
+------+-----------+
| id | title |
+------+-----------+
| (PK) | (VARCHAR) |
+------+-----------+
\/
One
to
many
\/
**Budget_operation_scope_cost_center:**
+----------------+---------------------------+
| cost_center_id | budget_operation_scope_id |
+----------------+---------------------------+
| (FK) | (FK) |
+----------------+---------------------------+
\/
Many
to
one
\/
**Budget_operation_scope:**
+------+-----------+-----------+
| id | title | budget_id |
+------+-----------+-----------+
| (PK) | (VARCHAR) | (FK) |
+------+-----------+-----------+
\/
Many
to
one
\/
**Budget:**
+------+-------+
| id | year |
+------+-------+
| (PK) | (INT) |
+------+-------+
Managed to do a query which returns assigned to budget cost centers list:
$query = $this->getEntityManager()
->createQueryBuilder()
->select('costCenter')
->from('ResourcesBundle:CostCenter', 'costCenter')
->leftJoin('costCenter.budgetOperationScope', 'budgetOperationScope')
->where('budgetOperationScope.budgetId = :budget')
->setParameter('budget', $budget)
->getQuery()->getResult();
Question: how to get cost centers, which are not assigned to budget?
This line is constraining your query too early and effectively making your left join a join:
->where('budgetOperationScope.budgetId = :budget')
You can move it into your left join like so:
->leftJoin('costCenter.budgetOperationScope', 'budgetOperationScope', 'WITH' 'budgetOperationScope.budgetId = :budget')
This way you will now get null rows for budgetOperationScope when a cost center has no budget.
So you can effectively do:
->where('budgetOperationScope IS NULL')
All together:
$query = $this->getEntityManager()
->createQueryBuilder()
->select('costCenter')
->from('ResourcesBundle:CostCenter', 'costCenter')
->leftJoin('costCenter.budgetOperationScope', 'budgetOperationScope', 'WITH' 'budgetOperationScope.budgetId = :budget')
->where('budgetOperationScope IS NULL')
->setParameter('budget', $budget)
->getQuery()->getResult();

Sqllite query on distinct or certain value

I have an android sqllite database. It has a text column called chainid.
I'd like to return all columns from rows with DISTINCT chainids || or where chainid is equal to: "none".
So e.g.:
| ID| Name | chainid |
| 1 | widgetname1 | 12345 |
| 2 | widgetname2 | 12345 |
| 3 | widgetname3 | "none" |
| 4 | widgetname4 | 49390 |
| 5 | widgetname5 | 49390 |
Given the above table I would like my query to return 3 rows with all columns for row 2, row3 and row5. -- So DISTINCT on chainid OR where chainid = "none" with the max id selected as the distinct row
Can I achieve this in one query?
I could return all and then process afterwards in java, but this is inefficient.
What about
select *
from table where id in
( select max(id)
from table
group by chainid
where chainid != 'none'
union
select id
from table
where chainid = 'none'
)

getting rid of filesort on WordPress MySQL query

An instance of WordPress that I manage goes down about once a day due to this monster MySQL query taking far too long:
SELECT SQL_CALC_FOUND_ROWS distinct wp_posts.*
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) LEFT JOIN wp_term_taxonomy ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id LEFT JOIN wp_ec3_schedule ec3_sch ON ec3_sch.post_id=id
WHERE 1=1 AND wp_posts.ID NOT IN ( SELECT tr.object_id
FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE tt.taxonomy = 'category' AND tt.term_id IN ('1050') ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND NOT EXISTS (SELECT *
FROM wp_term_relationships JOIN wp_term_taxonomy ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
WHERE wp_term_relationships.object_id = wp_posts.ID AND wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id IN (533,3567) ) AND ec3_sch.post_id IS NULL GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10;
What do I have to do to get rid of the very slow filesort? I would think that the multicolumn type_status_date index would be fast enough.
The EXPLAIN EXTENDED output is below.
+----+--------------------+-----------------------+--------+-----------------------------------+------------------+---------+---------------------------------------------------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------------------+--------+-----------------------------------+------------------+---------+---------------------------------------------------------------------------------+------+----------------------------------------------+
| 1 | PRIMARY | wp_posts | ref | type_status_date | type_status_date | 124 | const,const | 7034 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | wp_term_relationships | ref | PRIMARY | PRIMARY | 8 | bwog_wordpress_w.wp_posts.ID | 373 | Using index |
| 1 | PRIMARY | wp_term_taxonomy | eq_ref | PRIMARY | PRIMARY | 8 | bwog_wordpress_w.wp_term_relationships.term_taxonomy_id | 1 | Using index |
| 1 | PRIMARY | ec3_sch | ref | post_id_index | post_id_index | 9 | bwog_wordpress_w.wp_posts.ID | 1 | Using where; Using index |
| 3 | DEPENDENT SUBQUERY | wp_term_taxonomy | range | PRIMARY,term_id_taxonomy,taxonomy | term_id_taxonomy | 106 | NULL | 2 | Using where |
| 3 | DEPENDENT SUBQUERY | wp_term_relationships | eq_ref | PRIMARY,term_taxonomy_id | PRIMARY | 16 | bwog_wordpress_w.wp_posts.ID,bwog_wordpress_w.wp_term_taxonomy.term_taxonomy_id | 1 | Using index |
| 2 | DEPENDENT SUBQUERY | tt | const | PRIMARY,term_id_taxonomy,taxonomy | term_id_taxonomy | 106 | const,const | 1 | |
| 2 | DEPENDENT SUBQUERY | tr | eq_ref | PRIMARY,term_taxonomy_id | PRIMARY | 16 | func,const | 1 | Using index |
+----+--------------------+-----------------------+--------+-----------------------------------+------------------+---------+---------------------------------------------------------------------------------+------+----------------------------------------------+
8 rows in set, 2 warnings (0.05 sec)
And CREATE TABLE:
CREATE TABLE `wp_posts` (
`ID` bigint(20) unsigned NOT NULL auto_increment,
`post_author` bigint(20) unsigned NOT NULL default '0',
`post_date` datetime NOT NULL default '0000-00-00 00:00:00',
`post_date_gmt` datetime NOT NULL default '0000-00-00 00:00:00',
`post_content` longtext NOT NULL,
`post_title` text NOT NULL,
`post_excerpt` text NOT NULL,
`post_status` varchar(20) NOT NULL default 'publish',
`comment_status` varchar(20) NOT NULL default 'open',
`ping_status` varchar(20) NOT NULL default 'open',
`post_password` varchar(20) NOT NULL default '',
`post_name` varchar(200) NOT NULL default '',
`to_ping` text NOT NULL,
`pinged` text NOT NULL,
`post_modified` datetime NOT NULL default '0000-00-00 00:00:00',
`post_modified_gmt` datetime NOT NULL default '0000-00-00 00:00:00',
`post_content_filtered` text NOT NULL,
`post_parent` bigint(20) unsigned NOT NULL default '0',
`guid` varchar(255) NOT NULL default '',
`menu_order` int(11) NOT NULL default '0',
`post_type` varchar(20) NOT NULL default 'post',
`post_mime_type` varchar(100) NOT NULL default '',
`comment_count` bigint(20) NOT NULL default '0',
`robotsmeta` varchar(64) default NULL,
PRIMARY KEY (`ID`),
KEY `post_name` (`post_name`),
KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`),
KEY `post_parent` (`post_parent`),
KEY `post_date` (`post_date`),
FULLTEXT KEY `post_related` (`post_title`,`post_content`)
)
Warnings:
mysql> SHOW warnings \G
*************************** 1. row ***************************
Level: Note
Code: 1276
Message: Field or reference 'bwog_wordpress_w.wp_posts.ID' of SELECT #3 was resolved in SELECT #1
*************************** 2. row ***************************
Level: Note
Code: 1003
Message: select distinct sql_calc_found_rows `bwog_wordpress_w`.`wp_posts`.`ID` AS `ID`,`bwog_wordpress_w`.`wp_posts`.`post_author` AS `post_author`,`bwog_wordpress_w`.`wp_posts`.`post_date` AS `post_date`,`bwog_wordpress_w`.`wp_posts`.`post_date_gmt` AS `post_date_gmt`,`bwog_wordpress_w`.`wp_posts`.`post_content` AS `post_content`,`bwog_wordpress_w`.`wp_posts`.`post_title` AS `post_title`,`bwog_wordpress_w`.`wp_posts`.`post_excerpt` AS `post_excerpt`,`bwog_wordpress_w`.`wp_posts`.`post_status` AS `post_status`,`bwog_wordpress_w`.`wp_posts`.`comment_status` AS `comment_status`,`bwog_wordpress_w`.`wp_posts`.`ping_status` AS `ping_status`,`bwog_wordpress_w`.`wp_posts`.`post_password` AS `post_password`,`bwog_wordpress_w`.`wp_posts`.`post_name` AS `post_name`,`bwog_wordpress_w`.`wp_posts`.`to_ping` AS `to_ping`,`bwog_wordpress_w`.`wp_posts`.`pinged` AS `pinged`,`bwog_wordpress_w`.`wp_posts`.`post_modified` AS `post_modified`,`bwog_wordpress_w`.`wp_posts`.`post_modified_gmt` AS `post_modified_gmt`,`bwog_wordpress_w`.`wp_posts`.`post_content_filtered` AS `post_content_filtered`,`bwog_wordpress_w`.`wp_posts`.`post_parent` AS `post_parent`,`bwog_wordpress_w`.`wp_posts`.`guid` AS `guid`,`bwog_wordpress_w`.`wp_posts`.`menu_order` AS `menu_order`,`bwog_wordpress_w`.`wp_posts`.`post_type` AS `post_type`,`bwog_wordpress_w`.`wp_posts`.`post_mime_type` AS `post_mime_type`,`bwog_wordpress_w`.`wp_posts`.`comment_count` AS `comment_count`,`bwog_wordpress_w`.`wp_posts`.`robotsmeta` AS `robotsmeta` from `bwog_wordpress_w`.`wp_posts` left join `bwog_wordpress_w`.`wp_term_relationships` on((`bwog_wordpress_w`.`wp_term_relationships`.`object_id` = `bwog_wordpress_w`.`wp_posts`.`ID`)) left join `bwog_wordpress_w`.`wp_term_taxonomy` on((`bwog_wordpress_w`.`wp_term_taxonomy`.`term_taxonomy_id` = `bwog_wordpress_w`.`wp_term_relationships`.`term_taxonomy_id`)) left join `bwog_wordpress_w`.`wp_ec3_schedule` `ec3_sch` on((`bwog_wordpress_w`.`ec3_sch`.`post_id` = `bwog_wordpress_w`.`wp_posts`.`ID`)) where ((not(<in_optimizer>(`bwog_wordpress_w`.`wp_posts`.`ID`,<exists>(select 1 AS `Not_used` from `bwog_wordpress_w`.`wp_term_relationships` `tr` join `bwog_wordpress_w`.`wp_term_taxonomy` `tt` where ((`bwog_wordpress_w`.`tr`.`term_taxonomy_id` = '3572') and ('category' = _utf8'category') and (<cache>(`bwog_wordpress_w`.`wp_posts`.`ID`) = `bwog_wordpress_w`.`tr`.`object_id`)))))) and (`bwog_wordpress_w`.`wp_posts`.`post_type` = _utf8'post') and (`bwog_wordpress_w`.`wp_posts`.`post_status` = _utf8'publish') and (not(exists(select 1 AS `Not_used` from `bwog_wordpress_w`.`wp_term_relationships` join `bwog_wordpress_w`.`wp_term_taxonomy` where ((`bwog_wordpress_w`.`wp_term_relationships`.`term_taxonomy_id` = `bwog_wordpress_w`.`wp_term_taxonomy`.`term_taxonomy_id`) and (`bwog_wordpress_w`.`wp_term_relationships`.`object_id` = `bwog_wordpress_w`.`wp_posts`.`ID`) and (`bwog_wordpress_w`.`wp_term_taxonomy`.`taxonomy` = _utf8'category') and (`bwog_wordpress_w`.`wp_term_taxonomy`.`term_id` in (533,3567)))))) and isnull(`bwog_wordpress_w`.`ec3_sch`.`post_id`)) group by `bwog_wordpress_w`.`wp_posts`.`ID` order by `bwog_wordpress_w`.`wp_posts`.`post_date` desc limit 10,10
2 rows in set (0.00 sec)
The filesort is unavoidable due to the GROUP BY. However:
IN(SUBQUERY) gets run on every row of
the joined tables. Execute that subquery
before-hand as an independent query and then substitute the (now
static) results into the IN() function.
Do something similar with the EXISTS(SUBQUERY) function.
Consider using WordPress's super-cache plugin.
What are the warnings showing up in the EXPLAIN?
I know this old, but it's not a WordPress issue - it's a plugin issue (as usual).
You must be using a plugin called EventCalendar - that's what is causing this problem.
http://wpcal-archive.firetree.net/2008-January/002892.html

Resources