Getting Parent Child hierarchy - hierarchy

I'm trying to get ancestors of a child (dog) upto Level 5. For Example in attached picture I'll be sending "Spencer di Casa Massarelli" and in result want to have associated parents (both father and mother). In my DB structure I've used father_id and mother_id.
DB & version: 10.4.11-MariaDB
Table Script:
CREATE TABLE `dogs` (
`dog_id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`father_id` int(11) DEFAULT NULL,
`moter_id` int(11) DEFAULT NULL,
PRIMARY KEY (`dog_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `dogs` VALUES ('0', null, null, null);
INSERT INTO `dogs` VALUES ('1', 'Father', null, null);
INSERT INTO `dogs` VALUES ('2', 'Mother', null, null);
INSERT INTO `dogs` VALUES ('3', 'Father1', null, null);
INSERT INTO `dogs` VALUES ('4', 'Mother2', null, null);
INSERT INTO `dogs` VALUES ('5', 'Son', '1', '2');
INSERT INTO `dogs` VALUES ('6', 'Daughter', '3', '4');
INSERT INTO `dogs` VALUES ('7', 'GrandSon', '5', '6');
I've tried following self join query but the problem is I'm unable to get right parents i.e., parents(both father and mother) of first parent.
SELECT t1.name AS lev1,
t2.name AS lev2Father,
t3.name AS lev2Mother,
t4.name AS level3Father,
t5.name AS level3Mother,
t6.name AS level4Father,
t7.name AS level4Mother,
t8.name AS level5Father,
t9.name AS level5Mother,
t10.name AS level6Father,
t11.name AS level6Mother
FROM dogs AS t1
LEFT JOIN dogs AS t2 ON t2.dog_id = t1.father_id
LEFT JOIN dogs AS t3 ON t3.dog_id = t1.mother_id
LEFT JOIN dogs AS t4 ON t4.dog_id = t2.father_id
LEFT JOIN dogs AS t5 ON t5.dog_id = t2.mother_id
LEFT JOIN dogs AS t6 ON t6.dog_id = t4.father_id
LEFT JOIN dogs AS t7 ON t7.dog_id = t4.mother_id
LEFT JOIN dogs AS t8 ON t8.dog_id = t6.father_id
LEFT JOIN dogs AS t9 ON t9.dog_id = t6.mother_id
LEFT JOIN dogs AS t10 ON t10.dog_id = t8.father_id
LEFT JOIN dogs AS t11 ON t11.dog_id = t8.mother_id
WHERE t1.dog_id = 7

WITH RECURSIVE
cte AS (
SELECT *, 0 level, ' ' relation
FROM dogs
WHERE dog_id = 7
UNION ALL
SELECT dogs.*, level + 1, 'father'
FROM dogs
JOIN cte ON cte.father_id = dogs.dog_id
WHERE level < 5
UNION ALL
SELECT dogs.*, level + 1, 'mother'
FROM dogs
JOIN cte ON cte.mother_id = dogs.dog_id
WHERE level < 5
)
SELECT *
FROM cte
ORDER BY level, relation;
fiddle
Result
dog_id | name | father_id | mother_id | level | relation
-----: | :------- | --------: | --------: | ----: | :-------
7 | GrandSon | 5 | 6 | 0 |
5 | Son | 1 | 2 | 1 | father
6 | Daughter | 3 | 4 | 1 | mother
1 | Father | null | null | 2 | father
3 | Father1 | null | null | 2 | father
2 | Mother | null | null | 2 | mother
4 | Mother2 | null | null | 2 | mother

Related

How can I set multiple aliases for a single derived table in MariaDB 5.5?

Consider a database with three tables:
goods (Id is the primary key)
+----+-------+-----+
| Id | Name | SKU |
+----+-------+-----+
| 1 | Nails | 123 |
| 2 | Nuts | 456 |
| 3 | Bolts | 789 |
+----+-------+-----+
invoiceheader (Id is the primary key)
+----+--------------+-----------+---------+
| Id | Date | Warehouse | BuyerId |
+----+--------------+-----------+---------+
| 1 | '2021-10-15' | 1 | 223 |
| 2 | '2021-09-18' | 1 | 356 |
| 3 | '2021-07-13' | 2 | 1 |
+----+--------------+-----------+---------+
invoiceitems (Id is the primary key)
+----+----------+--------+-----+-------+
| Id | HeaderId | GoodId | Qty | Price |
+----+----------+--------+-----+-------+
| 1 | 1 | 1 | 15 | 1.1 |
| 2 | 1 | 3 | 7 | 1.5 |
| 3 | 2 | 1 | 12 | 1.5 |
| 4 | 3 | 3 | 3 | 1.3 |
+----+----------+--------+-----+-------+
What I'm trying to do is to get the MAX(invoiceheader.Date) for every invoiceitems.GoodId. Or, in everyday terms, to find out, preferably in a single query, when was the last time any of the goods were sold, from a specific warehouse.
To do that, I'm using a derived query, and the solution proposed here . In order to be able to do that, I think that I need to have a way of giving multiple (well, two) aliases for a derived table.
My query looks like this at the moment:
SELECT tmp.* /* placing the second alias here, before or after tmp.* doesn't work */
FROM ( /* placing the second alias, tmpClone, here also doesn't work */
SELECT
invoiceheader.Id,
invoiceheader.Date,
invoiceitems.HeaderId,
invoiceitems.Id,
invoiceitems.GoodId
FROM invoiceheader
LEFT JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
WHERE invoiceheader.Warehouse = 3
AND invoiceheader.Date > '0000-00-00 00:00:00'
AND invoiceheader.Date IS NOT NULL
AND invoiceheader.Date > ''
AND invoiceitems.GoodId > 0
ORDER BY
invoiceitems.GoodId ASC,
invoiceheader.Date DESC
) tmp, tmpClone /* this doesn't work with or without a comma */
INNER JOIN (
SELECT
invoiceheader.Id,
MAX(invoiceheader.Date) AS maxDate
FROM tmpClone
WHERE invoiceheader.Warehouse = 3
GROUP BY invoiceitems.GoodId
) headerGroup
ON tmp.Id = headerGroup.Id
AND tmp.Date = headerGroup.maxDate
AND tmp.HeaderId = headerGroup.Id
Is it possible to set multiple aliases for a single derived table? If it is, how should I do it?
I'm using 5.5.52-MariaDB.
you can use both (inner select) and left join to achieve this for example:
select t1.b,(select t2.b from table2 as t2 where t1.x=t2.x) as 'Y' from table as t1 Where t1.y=(select t3.y from table3 as t3 where t2.a=t3.a)
While this doesn't answer my original question, it does solve the problem from which the question arose, and I'll leave it here in case anyone ever comes across a similar issue.
The following query does what I'd intended to do - find the newest sale date for the goods from the specific warehouse.
SELECT
invoiceheader.Id,
invoiceheader.Date,
invoiceitems.HeaderId,
invoiceitems.Id,
invoiceitems.GoodId
FROM invoiceheader
INNER JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
INNER JOIN (
SELECT
MAX(invoiceheader.Date) AS maxDate,
invoiceitems.GoodId
FROM invoiceheader
INNER JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
WHERE invoiceheader.Warehouse = 3
AND invoiceheader.Date > '0000-00-00 00:00:00'
AND invoiceheader.Date IS NOT NULL
AND invoiceheader.Date > ''
GROUP BY invoiceitems.GoodId
) tmpDate
ON invoiceheader.Date = tmpDate.maxDate
AND invoiceitems.GoodId = tmpDate.GoodId
WHERE invoiceheader.Warehouse = 3
AND invoiceitems.GoodId > 0
ORDER BY
invoiceitems.GoodId ASC,
invoiceheader.Date DESC
The trick was to join by taking into consideration two things - MAX(invoiceheader.Date) and invoiceitems.GoodId - since one GoodId can only appear once inside a specific invoiceheader / invoiceitems JOINing (strict limit imposed on the part of the code which inserts into invoiceitems).
Whether this is the most optimal solution (ignoring the redundant conditions in the query), and whether it would scale well, remains to be seen - it has been tested on tables with ~5000 entries for invoiceheader, ~60000 entries for invoiceitems, and ~4000 entries for goods. Execution time was < 1 sec.

SQLite select row with multiple condition from other table

I'm having probleme with a SQL request.
I have two tables:
main table is
Id | Name
1 | Name_1
2 | Name_2
keyword table
Id | _mainId | key
1 | 1 | kw1
2 | 1 | kw2
3 | 1 | kw3
4 | 2 | kw2
5 | 2 | kw4
I would like a request which return the Id and Name of the mane table with all the keywords selected
something like this :
SELECT DISTINCT(t1.Id), t1.Name
FROM main t1
INNER JOIN keywords t2 ON t2._Main = t1.Id
WHERE t2.keyword = 'kw2' AND t2.keyword = 'kw4';
In the query below, the subquery aliased as t2 identifies all IDs having both the keywords 'kw2' and 'kw4'. I then join the main table to this subquery to bring in the name information for those matching IDs.
SELECT t1.Id, t1.Name
FROM main t1
INNER JOIN
(
SELECT _mainId
FROM keywords
WHERE keyword IN ('kw2', 'kw4')
GROUP BY _mainId
HAVING COUNT(DISTINCT keyword) = 2
) t2
ON t1.Id = t2._mainId
Try this:
SELECT DISTINCT
t1.Id, t1.Name
FROM
main t1
INNER JOIN keywords t2 ON t2._mainId=t1.Id
WHERE
t2.key IN ('kw2', 'kw4');

SQL SERVER merge two column, combine it, and count the same

I want to create a barcode by merge and combine two column.
here is my table :
ID | Items1 | Items2 | BArcode
001 | Shirt | CPU |
002 | Shirt | CPU |
001 | Shoes | Monitor |
002 | Jacket | Monitor |
001 | Shoes | CPU |
002 | | Keyboard |
002 | | Keyboard |
001 | Shirt | Keyboard |
002 | Shirt | |
The barcode created based on ID+Item1/Items2+Count. The count get from counting how many times one ID have oredered the same item. I want it to display only the data that haven't generated a barcode, so it's when the Barcode column value is null, from the above table the Barcode is null:
ID | Barcode |
001 | 001Shirt1 |
002 | 002Shirt1 |
001 | 001Shoes1 |
002 | 002Jacket1 |
001 | 001Shoes2 |
001 | 001Shirt2 |
002 | 002Shirt2 |
001 | 001CPU1 |
002 | 002CPU1 |
001 | 001Monitor1 |
002 | 002Monitor1 |
001 | 001CPU2 |
002 | 002Keyboard1 |
002 | 002Keyboard2 |
001 | 001Keyboard1 |
here is my first code :
Dim strcommand As String = "select [ID], ([ID] + [Items1])
as Barcode from tbl_Request where [Items1] != 'null'
and Barcode = 'null' union select ([ID] + [Items2])
from tbl_Request where [Items2] != 'Null' and Barcode = 'null'"
it doesn't work. it say "All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists". on my code above I haven't implement the counting yet. does anyone know how to do it?
Thanks in advances....
You can use this query to generate the barcode values:
;with cte as
(select id, item1 item, row_number() over (partition by id, item1 order by getdate()) rn
from items
where item1 is not null and barcode is null
union
select id, item2 item, row_number() over (partition by id, item2 order by getdate()) rn
from items
where item2 is not null and barcode is null)
select id, cast(id as varchar) + item + cast(rn as varchar) barcode
from cte
If you wanted to add this to a new table, say tbl_barcode with columns id and barcode, you would do this:
;with cte as
(select id, item1 item, row_number() over (partition by id, item1 order by getdate()) rn
from items
where item1 is not null and barcode is null
union
select id, item2 item, row_number() over (partition by id, item2 order by getdate()) rn
from items
where item2 is not null and barcode is null)
insert into tbl_barcode (id, barcode)
select id, cast(id as varchar) + item + cast(rn as varchar) barcode
from cte
The error that you are getting is that the union join that you have created does not contain the same fields in the second select statement, as your original select statement. SQL UNION Operator, Notice that each SELECT statement within the UNION must have the same number of columns.
So therefore you will need to change
select ([ID] + [Items2])
to
select [ID], ([ID] + [Items2])
declare #x table (ID varchar(20),Items1 VARCHAR(10),Items2 VARCHAR(10),BARCODE INT)
INSERT INTO #x
(ID,Items1,Items2,BARCODE)
VALUES ('001','Shirt','CPU',NULL)
INSERT INTO #x
(ID,Items1,Items2,BARCODE)
VALUES ('001',NULL,'Monitor',NULL)
INSERT INTO #x
(ID,Items1,Items2,BARCODE)
VALUES ('002','TRouser','Monitor',NULL)
select ID,
Case when Items1 IS NOT NULL Then ID +Items1+
CAST(DENSE_RANK()OVER(PARTITION by Items1 order by Items1 desc)AS VARCHAR)
when Items2 IS NOT NULL Then ID +Items2+
CAST(DENSE_RANK()OVER(PARTITION by Items2 order by Items1 desc)AS VARCHAR)
ELSE '' END AS Barcode from #x

Can't join two tables in sqlite

i have two tables:
CREATE TABLE "object_comment"
("object_id" INTEGER PRIMARY KEY NOT NULL,
"object_comment_text" TEXT,
"object_comment_title" TEXT,
"object_comment_date" DATETIME)
and
CREATE TABLE "object_comment_mark"
("object_id" INTEGER PRIMARY KEY DEFAULT null,
"object_comment_mark_value" FLOAT DEFAULT null,
"object_comment_mark_date" DATETIME DEFAULT null)
I need to join them with the object_id field but the unique rows should present in results too. (there are some equal object_id values which I need to join in one row and some object_id values are different but they should be in the result table)
Now I have this select query:
SELECT *
FROM object_comment
LEFT OUTER JOIN object_comment_mark ON object_comment.object_id = object_comment_mark.object_id
But in this case I don't have the rows from the second table where the object_id has unique value. Any help?
EDIT: what I need
object_comment
1 | bla-bla | first | 2013
2 | be-be | sec | 2014
object_comment_mark
1 | 5 | 2013
4 | 3 | 2013
result
1 |bla-bla | first| 2013 | 5 | 2013
2 | be-be | sec | 2014 | |
4 | | | | 3 | 2013
What you want is full outer join, which is not supported by SQLite.
Instead, you could combine a left join and the unmatched (NULL) records of a right join.
A right join isn't supported either, so use a left join with the two tables swapped:
SELECT oc.*, ocm.*
FROM object_comment AS oc
LEFT JOIN object_comment_mark AS ocm ON oc.object_id = ocm.object_id
UNION ALL
SELECT oc.*, ocm.*
FROM object_comment_mark AS ocm
LEFT JOIN object_comment AS oc ON oc.object_id = ocm.object_id
WHERE oc.object_id IS NULL
Alternatively, search for unmatched records by hand:
SELECT oc.*, ocm.*
FROM object_comment AS oc
LEFT JOIN object_comment_mark AS ocm ON oc.object_id = ocm.object_id
UNION ALL
SELECT NULL, NULL, NULL, NULL, *
FROM object_comment_mark
WHERE object_id NOT IN (SELECT object_id
FROM object_comment)
I'm not understanding exactly your question...
Is this you need?
SELECT * FROM object_comment
INNER JOIN object_comment_mark ON object_comment.object_id = object_comment_mark.object_id
UNION ALL
SELECT *, NULL, NULL, NULL, NULL FROM object_comment

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