Pivoting in MySQL - only works on one row at a time? - mysql

I'm trying to select assets from RT's database with the the values for a set of custom fields as tables. Relevant tables are as follows:
mysql> describe AT_Assets;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| Type | int(11) | NO | MUL | 0 | |
| Name | varchar(200) | NO | MUL | NULL | |
| Description | varchar(255) | YES | | NULL | |
| Status | varchar(20) | YES | | NULL | |
| URI | varchar(255) | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)
mysql> describe CustomFields;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| Name | varchar(200) | YES | | NULL | |
| Type | varchar(200) | YES | | NULL | |
| RenderType | varchar(64) | YES | | NULL | |
| MaxValues | int(11) | YES | | NULL | |
| Pattern | text | YES | | NULL | |
| Repeated | smallint(6) | NO | | 0 | |
| BasedOn | int(11) | YES | | NULL | |
| ValuesClass | varchar(64) | YES | | NULL | |
| Description | varchar(255) | YES | | NULL | |
| SortOrder | int(11) | NO | | 0 | |
| LookupType | varchar(255) | NO | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Disabled | smallint(6) | NO | | 0 | |
+---------------+-------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)
mysql> describe ObjectCustomFieldValues;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| CustomField | int(11) | NO | MUL | NULL | |
| ObjectType | varchar(255) | NO | | NULL | |
| ObjectId | int(11) | NO | | NULL | |
| SortOrder | int(11) | NO | | 0 | |
| Content | varchar(255) | YES | MUL | NULL | |
| LargeContent | longblob | YES | | NULL | |
| ContentType | varchar(80) | YES | | NULL | |
| ContentEncoding | varchar(80) | YES | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Disabled | smallint(6) | NO | | 0 | |
+-----------------+--------------+------+-----+---------+----------------+
This query successfully gets me a listing of all assets, but repeats the asset in a separate column for each custom field value:
SELECT AT_Assets.Name, AT_Assets.description, CustomFields.Name, ObjectCustomFieldValues.content FROM ObjectCustomFieldValues inner join CustomFields on ObjectCustomFieldValues.CustomField = CustomFields.id inner join AT_Assets on AT_Assets.id = ObjectCustomFieldValues.ObjectID order by AT_Assets.description;
So I did some reading, and learned how to pivot. Now I have this:
SELECT at_assets.name,
at_assets.description AS "Asset Tag",
Max(CASE
WHEN customfields.name = "make" THEN
objectcustomfieldvalues.content
END) AS "Make",
Max(CASE
WHEN customfields.name = "model" THEN
objectcustomfieldvalues.content
END) AS "Model",
Max(CASE
WHEN customfields.name = "primary user" THEN
objectcustomfieldvalues.content
END) AS "Primary User",
Max(CASE
WHEN customfields.name = "hostname" THEN
objectcustomfieldvalues.content
END) AS "Hostname",
Max(CASE
WHEN customfields.name = "os" THEN objectcustomfieldvalues.content
END) AS "OS",
Max(CASE
WHEN customfields.name = "purchase date (if known)" THEN
objectcustomfieldvalues.content
END) AS "Purchase Date"
FROM objectcustomfieldvalues
INNER JOIN customfields
ON objectcustomfieldvalues.customfield = customfields.id
INNER JOIN at_assets
ON at_assets.id = objectcustomfieldvalues.objectid
WHERE at_assets.id = 5
ORDER BY at_assets.description;
Which works great, when I'm specifying a single asset. However, I would like this to run across every asset. Otherwise I need a Python script to run this hundreds of times manually incrementing the asset id, which is fairly inelegant. How do I go about getting a full list?

You learned everything about the pivot, except adding the group by.
Add the following line after the where:
group by at_assets.name, at_assets.description
To see more than one line, remove or adjust the where clause.
What is happening with your query is the MySQL recognizes it as an aggregation query, because it is using MAX(). There is no group by, so it produces one row -- an aggregation of all the rows.
What about the variables at_assets.name and at_assets.description in the select clause? you might ask. Well, most SQL engines would balk and produce an error. These variables are neither in the group by nor the argument to an aggregation function. MySQL has a (mis)feature called hidden columns that allows such references. However, the values come from arbitrary rows in the source data, so the value are not meaningful unless all values in the group are the same.

you just need group by here. and dont specify the asset name.
change this
WHERE at_assets.id = 5
ORDER BY at_assets.description;
to
group by at_assets.name
ORDER BY at_assets.description;

Related

How to add a date selection in sql

I want to be able to select classes that are starting on or after the next two hours up until the end of tomorrow's date but I am not sure of how to do this.
My current sql is below, I have only been able to select classes that are after today's date and after the current time. I want to be able to only return classes that start two hours after now up until the end of tomorrows date.
I am able to pass the current date and current time into my node.js function that will construct the sql statement. Also, I have access to moment.js library if I need to use this I could.
Any help would be appreciated.
SELECT DISTINCT b.name
, a.time
FROM class a
Inner join (SELECT class_id, count(clientid)
FROM bookings
GROUP BY class_id
HAVING count(clientid) < 10) as openClasses on
a.class_id = openClasses.class_id
JOIN class_detail b
ON a.class_id = b.id
JOIN branch c
ON a.branch_id = c.id
WHERE c.level <= ( SELECT d.level
FROM client d
WHERE d.facebook_id = 'xxxxxx'
)
AND a.date = '2016-08-17'
AND a.time >= '13.00.00';
My tables are as follows:
BOOKINGS
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| CLIENT_ID | int(11) | NO | | NULL | |
| CLASS_ID | int(11) | NO | | NULL | |
| STATUS | varchar(10) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
mysql> show fields from BRANCH;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| NAME | char(50) | NO | | NULL | |
| CONTACT_NO | char(50) | YES | | NULL | |
| MAP_IMG_PATH | char(200) | YES | | NULL | |
| ADDRESS | char(200) | YES | | NULL | |
| LEVEL | int(2) | NO | | NULL | |
| LOCATION | int(10) | YES | | NULL | |
| SECTOR_NAME | varchar(45) | YES | | NULL | |
| SECTOR_MAP_IMG_PATH | char(200) | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
mysql> show fields from CLIENT;
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DOB | int(8) | NO | | NULL | |
| LOCAL_BRANCH | int(10) | YES | | NULL | |
| FACEBOOK_ID | char(50) | NO | | NULL | |
| START_DATE | int(8) | NO | | NULL | |
| EMAIL | char(50) | YES | | NULL | |
| PIN | int(4) | YES | | NULL | |
| END_DATE | int(8) | NO | | NULL | |
| LEVEL | int(2) | YES | | NULL | |
| TEL | varchar(20) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
mysql> show fields from CLASS_DETAIL;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DESCRIPTION | char(200) | NO | | NULL | |
| CATEGORY | varchar(4) | YES | | NULL | |
| ACHIEVE_TYPE | char(200) | YES | | NULL | |
| IMG_M | varchar(200) | YES | | NULL | |
| IMG_F | varchar(200) | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
mysql> show fields from CLASS;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| CLASS_ID | int(10) | YES | | NULL | |
| BRANCH_ID | int(10) | NO | | NULL | |
| DURATION | int(3) | YES | | NULL | |
| DATE | date | NO | | NULL | |
| TIME | time | NO | | NULL | |
| STATUS | char(1) | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
7 rows in set (0.11 sec)

Merge data from two cells from the same column in different rows in MySQL/MariaDB

I am having trouble searching for an answer to this question, because of my lack of knowledge about the terminology and SQL, even though I know it probably exists.
I have a database with the following tables:
desc pkm;
+-----------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+-------+
| pkm_code | int(11) | NO | PRI | NULL | |
| pkm_name | varchar(32) | NO | UNI | NULL | |
| pkm_category | varchar(32) | NO | | NULL | |
| pkm_description | varchar(1280) | NO | | NULL | |
| pkm_weight | float | NO | | NULL | |
| evolution_code | int(11) | YES | MUL | NULL | |
+-----------------+---------------+------+-----+---------+-------+
desc poketype;
+---------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+------------+------+-----+---------+-------+
| pkm_code | int(11) | NO | PRI | NULL | |
| type_code | int(11) | NO | PRI | NULL | |
| poketype_is_primary | tinyint(1) | NO | | NULL | |
+---------------------+------------+------+-----+---------+-------+
desc type;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| type_code | int(11) | NO | PRI | NULL | |
| type_name | varchar(32) | NO | UNI | NULL | |
+-----------+-------------+------+-----+---------+-------+
And so far I have the following SQL command:
SELECT pkm.pkm_code, pkm.pkm_name,type.type_name FROM poketype
JOIN pkm ON pkm.pkm_code=poketype.pkm_code
JOIN type ON poketype.type_code=type.type_code
WHERE pkm.pkm_code<=151
ORDER BY pkm_code;
Which displays the primary and secondary types on separate lines.
How would I get both types to display on the same row for dual-type pokemon?
My current results:
+-----------+-------------+-----------+
| pkm_code | pkm_name | type_name |
+-----------+-------------+-----------+
| 1 | Bulbasaur | grass |
| 1 | Bulbasaur | poison |
Desired results:
+-----------+-------------+-------------+
| pkm_code | pkm_name | type_name |
+-----------+-------------+-------------+
| 1 | Bulbasaur | grass,poison|
(Yes, bulbasaur is a dual type. I was surprised too!)
Use mysql's group_concat() function to combine values from different records in a single value:
SELECT pkm.pkm_code, pkm.pkm_name, group_concat(type.type_name) as typename FROM poketype
JOIN pkm ON pkm.pkm_code=poketype.pkm_code
JOIN type ON poketype.type_code=type.type_code
WHERE pkm.pkm_code<=151
GROUP BY pkm.pkm_code, pkm.pkm_name;

MySQL Unknown column in where clause?

I have two databases.
One is called INFO with three tables (Stories, Comments, Replies)
Stories has the following fields
+--------------+----------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------+------+-----+---------------------+-----------------------------+
| storyID | int(11) | NO | PRI | NULL | |
| originalURL | varchar(500) | YES | | NULL | |
| originalDate | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| numDiggs | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| diggURL | varchar(500) | YES | | NULL | |
| rating | varchar(50) | YES | | NULL | |
| title | varchar(200) | YES | | NULL | |
| summary | varchar(10000) | YES | | NULL | |
| uploaderID | varchar(50) | YES | | NULL | |
| imageURL | varchar(500) | YES | | NULL | |
| category1 | varchar(50) | YES | | NULL | |
| category2 | varchar(50) | YES | | NULL | |
| uploadDate | timestamp | NO | | 0000-00-00 00:00:00 | |
| num | int(11) | YES | | NULL | |
+--------------+----------------+------+-----+---------------------+-----------------------------+
Another database is called Data with one table (User). Fields shown below:
+-------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+-------+
| userID | varchar(50) | NO | PRI | NULL | |
| numStories | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| numReplies | int(11) | YES | | NULL | |
| numStoryDiggs | int(11) | YES | | NULL | |
| numCommentReplies | int(11) | YES | | NULL | |
| numReplyDiggs | int(11) | YES | | NULL | |
| numStoryComments | int(11) | YES | | NULL | |
| numStoryReplies | int(11) | YES | | NULL | |
+-------------------+-------------+------+-----+---------+-------+
User.userID is full of thousands of unique names. All other fields are currently NULL. The names in User.userID correspond to the names in Stories.uploaderID.
I need to, for each userID in User, count the number of stories uploaded from (i.e. num) Stories for the corresponding name and insert this value into User.numStories.
The query which I have come up with (which produces an error) is:
INSERT INTO DATA.User(numStories)
SELECT count(num)
FROM INFO.Stories
WHERE INFO.Stories.uploaderID=DATA.User.userID;
The error I get when running this query is
Unknown column 'DATA.User.userID' in 'where clause'
Sorry if this is badly explained. I will try and re-explain if need be.
You aren't creating new entries in the User table, you're updating existing ones. Hence, insert isn't the right syntax here, but rather update:
UPDATE DATA.User u
JOIN (SELECT uploaderID, SUM(num) AS sumNum
FROM INFO.Stories
GROUP BY uploadedID) i ON i.uploaderID = u.userID
SET numStories = sumNum
EDIT:
Some clarification, as requested in the comments.
The inner query sums the num in Stories per uploaderId. The updates statement updates the numStories in User the the calculated sum of the inner query of the matching id.

multi join mysql query taking too long to execute

I have 4 tables as below ,i am trying to join these tables but the query is taking too long to execute.Please tell me how do i optimize this.
Trying to do below
1) using a sub query i am creating a table based on input date range
2) i require to group result based on bank then on district and then on state,so that i can filter results on front end as State-->District-->Bank
3) Also i need to avoid some junk data which i am doing using not like clause.
select substring(a.ifsc,1,4) as code,
s.new_state as state,
s.state_id as stid,
d.new_dist as dist,
b.ifbank as bank,
count(a.amt) as num,
sum(a.amt) as amt from
(SELECT * FROM mtr where orgdate between '$fdate_new' and '$tdate_new')
as a JOIN ifsc b on b.ifscd=a.ifsc
JOIN user c on a.excd=c.mtr
JOIN state_mapping s on b.state=s.org_state
JOIN dist_mapping d on b.dist=d.org_dist
where
s.state_id ='$stid' and
TRIM(d.new_dist) <> '' and
d.new_dist IS NOT NULL
group by bank,dist order by amt desc;
dist_mapping table
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| org_dist | varchar(20) | YES | | NULL | |
| new_dist | varchar(20) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
ifsc table
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| ifscd | varchar(11) | NO | PRI | | |
| ifscbr | varchar(40) | YES | | NULL | |
| ifbank | varchar(40) | YES | | NULL | |
| newifsc | varchar(11) | YES | | NULL | |
| dist | varchar(20) | YES | | NULL | |
| state | varchar(20) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
state_mapping table
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| org_state | varchar(20) | YES | | NULL | |
| new_state | varchar(20) | YES | | NULL | |
| state_id | int(2) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
user table
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| excode | int(2) | YES | | NULL | |
| mtr | int(2) | YES | | NULL | |
| exname | varchar(40) | YES | | NULL | |
| country | varchar(10) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
mysql> desc mtr;
+---------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| excd | int(2) | NO | PRI | 0 | |
| orgdate | date | YES | | NULL | |
| amt | double(12,2) | YES | | NULL | |
| obank | int(1) | YES | | NULL | |
| brcd | int(5) | YES | | NULL | |
| brname | varchar(40) | YES | | NULL | |
| rname | varchar(40) | YES | | NULL | |
| bname | varchar(40) | YES | | NULL | |
| baddr | varchar(60) | YES | | NULL | |
| mob | varchar(32) | YES | | NULL | |
| ifsc | varchar(12) | YES | | NULL | |
+---------+---------------------+------+-----+---------+-------+
Subquery takes more time compare to join Please try this
select substring(a.ifsc,1,4) as code,
s.new_state as state,
s.state_id as stid,
d.new_dist as dist,
b.ifbank as bank,
count(a.amt) as num,
sum(a.amt) as amt
From mtr as a
JOIN ifsc b on b.ifscd=a.ifsc and orgdate between '$fdate_new' and '$tdate_new'
JOIN user c on a.excd=c.mtr
JOIN state_mapping s on b.state=s.org_state
JOIN dist_mapping d on b.dist=d.org_dist
where
s.state_id ='$stid' and `enter code here`
TRIM(d.new_dist) <> '' and
d.new_dist IS NOT NULL
group by bank,dist order by amt desc;

How to make this SQL query faster?

I have the following query:
SELECT DISTINCT `movies_manager_movie`.`id`,
`movies_manager_movie`.`title`,
`movies_manager_movie`.`original_title`,
`movies_manager_movie`.`synopsis`,
`movies_manager_movie`.`keywords`,
`movies_manager_movie`.`release_date`,
`movies_manager_movie`.`rating`,
`movies_manager_movie`.`poster_web_url`,
`movies_manager_movie`.`has_poster`,
`movies_manager_movie`.`number`,
`movies_manager_movie`.`has_sources`,
`movies_manager_movie`.`season_id`,
`movies_manager_movie`.`created`,
`movies_manager_movie`.`updated`,
`movies_manager_moviecache`.`activity_name`
FROM `movies_manager_movie`
LEFT OUTER JOIN `movies_manager_moviecache` ON (`movies_manager_movie`.`id` = `movies_manager_moviecache`.`movie_id`)
WHERE (`movies_manager_movie`.`has_sources` = 1
AND (`movies_manager_moviecache`.`team_member_id` IN (
SELECT U0.`id` FROM `movies_manager_movieteammember` U0
INNER JOIN `movies_manager_movieteammemberactivity` U1 ON (U0.`id` = U1.`team_member_id`)
WHERE U1.`movie_id` = 3588 )
AND `movies_manager_movie`.`number` IS NULL
)
AND NOT (`movies_manager_movie`.`id` = 3588 ))
ORDER BY `movies_manager_moviecache`.`activity_name` DESC LIMIT 3;
This query can take up to 3 seconds and I'm very surprise since I got indexes everywhere and no more than 35 rows in each of my MyIsam tables, using the latest MySQL version.
I cached everything I could but I have at least to run this one 20000 times every day, which is approximately 16 h of waiting for loading. And I'm pretty sure none of my user (nor Google Bot) appreciate a 4 secondes waiting time for each page loading.
What could I do to make it faster ?
I thought about duplicating field from movie to moviecache since the all purpose of movie cache is to denormalize to complex join already.
I tried inlining the subquery to a list of ID but it surprisingly doubled the time of the query.
Tables:
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(120) | NO | UNI | NULL | |
| original_title | varchar(120) | YES | | NULL | |
| synopsis | longtext | YES | | NULL | |
| keywords | varchar(120) | YES | | NULL | |
| release_date | date | YES | | NULL | |
| rating | int(11) | NO | | NULL | |
| poster_web_url | varchar(255) | YES | | NULL | |
| has_poster | tinyint(1) | NO | | NULL | |
| number | int(11) | YES | | NULL | |
| season_id | int(11) | YES | MUL | NULL | |
| created | datetime | NO | | NULL | |
| updated | datetime | NO | | NULL | |
| has_sources | tinyint(1) | NO | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(120) | NO | UNI | NULL | |
| biography | longtext | YES | | NULL | |
| birth_date | date | YES | | NULL | |
| picture_web_url | varchar(255) | YES | | NULL | |
| allocine_link | varchar(255) | YES | | NULL | |
| created | datetime | NO | | NULL | |
| updated | datetime | NO | | NULL | |
| has_picture | tinyint(1) | NO | | NULL | |
| biography_linkyfied | longtext | YES | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| movie_id | int(11) | NO | MUL | NULL | |
| tag_slug | varchar(100) | YES | MUL | NULL | |
| team_member_id | int(11) | YES | MUL | NULL | |
| cast_rank | int(11) | YES | | NULL | |
| activity_name | varchar(30) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
Mysql tells me it's a slow query:
# Query_time: 3 Lock_time: 0 Rows_sent: 9 Rows_examined: 454128
Move movies_manager_movieteammemberactivity and movies_manager_movieteammember to your main join statement (so that you're doing a left outer between movies_manager_movie and the inner join product of the other 3 tables). This should speed up your query considerably.
Try this:
SELECT `movies_manager_movie`.`id`,
`movies_manager_movie`.`title`,
`movies_manager_movie`.`original_title`,
`movies_manager_movie`.`synopsis`,
`movies_manager_movie`.`keywords`,
`movies_manager_movie`.`release_date`,
`movies_manager_movie`.`rating`,
`movies_manager_movie`.`poster_web_url`,
`movies_manager_movie`.`has_poster`,
`movies_manager_movie`.`number`,
`movies_manager_movie`.`has_sources`,
`movies_manager_movie`.`season_id`,
`movies_manager_movie`.`created`,
`movies_manager_movie`.`updated`,
(
SELECT `movies_manager_moviecache`.`activity_name`
FROM `movies_manager_moviecache`
WHERE (`movies_manager_movie`.`id` = `movies_manager_moviecache`.`movie_id`
AND (`movies_manager_moviecache`.`team_member_id` IN (
SELECT U0.`id` FROM `movies_manager_movieteammember` U0
INNER JOIN `movies_manager_movieteammemberactivity` U1 ON (U0.`id` = U1.`team_member_id`)
WHERE U1.`movie_id` = 3588 )
AND `movies_manager_movie`.`number` IS NULL
) ) LIMIT 1) AS `activity_name`
FROM `movies_manager_movie`
WHERE (`movies_manager_movie`.`has_sources` = 1
AND NOT (`movies_manager_movie`.`id` = 3588 ))
ORDER BY `activity_name` DESC
LIMIT 3;
Let me know how that performs