I'm using vbulletin 5 and getting message from the host that MYSQL Query was killed because it was running over 1 minutes .. I looked at the query and feel there is something wrong with it .. though I don't have enough experience to judge
here is the query ..
SELECT DISTINCT node.starter AS nodeid
FROM node as node
JOIN closure AS closure ON node.nodeid = closure.child
LEFT JOIN node AS starter
ON starter.nodeid = IF(node.starter = 0, node.nodeid, node.starter)
WHERE node.contenttypeid <> 19
AND node.contenttypeid IN ('22','26','23','21','20','25')
AND closure.parent = '2'
AND node.nodeid <> closure.parent
AND node.contenttypeid <> '15'
AND node.userid <> '28030'
AND (node.public_preview = 1
OR
(
(
(
(
starter.parentid IN (1,2,3,6,13,14,15,16,17,18,19,20,21,22,23,24,25,26,247197,257065,7,8,9,12,51,59,62,27,32,33,36,44,45,50,35,34,37,38,39,40,61,60,57,43,42,46,47,28,29,30,31,41,48,49,52,53,54,55,56,58,63,65,64,247199,247200,66)
)
AND node.showapproved > 0
AND node.viewperms > 1
AND node.showpublished > 0
)
)
OR starter.parentid = 9 AND node.userid IN (0)
)
)
ORDER BY node.lastcontent DESC,node.nodeid ASC
LIMIT 500
Related
WITH t as (
SELECT *
FROM scd p
WHERE p.modified_date > FROM_UNIXTIME(1593060230)
AND ( p.main_id = 1
OR FIND_IN_SET(1, p.mult_ids) <> 0 )
ORDER BY modified_date DESC
LIMIT 2 OFFSET 0
),
del as (
SELECT
*
FROM t WHERE (status <> 1 AND status <> 2)
),
w_del as (
SELECT
*
FROM t WHERE (status = 1 OR status = 2)
)
SELECT w_del.*, del.* FROM w_del,del;
How do I achieve this with normal sub queries. I am using MySQL 5.7 and can't use CTEs. Im getting can't reuse table error if I use UNION/sub-queries. Is there a way to achieve this without temporary tables?
Please help.
You can just plug in the code for each alias . . . and keep doing that until you are at the base tables:
SELECT w_del.*, del.*
FROM (SELECT t.*
FROM (SELECT *
FROM scd p
WHERE p.modified_date > FROM_UNIXTIME(1593060230) AND
( p.main_id = 1 OR FIND_IN_SET(1, p.mult_ids) <> 0 )
ORDER BY modified_date DESC
LIMIT 2 OFFSET 0
) t
WHERE (status <> 1 AND status <> 2)
) w_del CROSS JOIN
(SELECT t.*
FROM (SELECT *
FROM scd p
WHERE p.modified_date > FROM_UNIXTIME(1593060230) AND
( p.main_id = 1 OR FIND_IN_SET(1, p.mult_ids) <> 0 )
ORDER BY modified_date DESC
LIMIT 2 OFFSET 0
) t
WHERE (status = 1 OR status = 2)
) del;
One critical point, though: The definition of t is using ORDER BY and LIMIT. If there are ties in the modified_date column, then the two subqueries could return different result sets. You have two choices to avoid a problem here:
Add additional keys to the ORDER BY to ensure that the sorting is stable (i.e. returns the same results each time because the combination of keys is unique).
Materialize the subquery using a temporary table.
Hello, you see here a screenshot of the table-structure, which I want to extract information from. It is a table from a messaging-system.
Two users, which write each other messages get a unique msgconv id.
Now, I would like to get the latest msg from each msgconv where a specific user is involved in, but the msg is not allowed to be deleted by the specific user.
This is my query at the moment:
SELECT v1.msgconv
, v1.timesent
, v1.msg
, v1.msgfrom
, v1.msgto
, v1.msgdel_sender
, v1.msgdel_receiver
FROM msg v1
LEFT
JOIN msg v2
ON v1.msgconv = v2.msgconv
AND v1.timesent < v2.timesent
WHERE v1.msgfrom = 69
AND v1.msgdel_sender = 0
OR v1.msgto = 69
AND v1.msgdel_receiver = 0
ORDER
BY timesent DESC
With this query I get 14 results and I don´t know why. What I should get is only the latest msg of each msgconv.
Can please someone help me with this, thank you
I would like to get the latest msg from each msgconv where a specific user is involved
If you are running MySQL 8.0, you can use ROW_NUMBER() to identify the records to display:
SELECT *
FROM (
SELECT
m.*,
ROW_NUMBER() OVER(PARTITION BY msgconv ORDER BY timestamp DESC) rn
FROM msg m
WHERE
( msgfrom = 69 AND msgdel_sender = 0 )
OR ( msgto = 69 AND msgdel_receiver = 0 )
) x
In earlier versions, you can use a NOT EXISTS condition with a correlated subquery:
SELECT *
FROM msg m
WHERE
(
( msgfrom = 69 AND msgdel_sender = 0 )
OR ( msgto = 69 AND msgdel_receiver = 0 )
)
AND NOT EXISTS (
SELECT 1
FROM msg m1
WHERE
(
( m1.msgfrom = 69 AND m1.msgdel_sender = 0 )
OR ( m1.msgto = 69 AND m1.msgdel_receiver = 0 )
)
AND m1.msgconv = m.msgconv
AND m1.timestamp > m.timestamp
)
The query starts by selecting all records that belong to the relevant user. Then, the NOT EXISTS condition filters out every record but the latest in each group of record having the same msgconv.
When I run this query, it took an average of 1.2421 seconds, which I think is slow, I have added indexing to every single possible column in those WHERE clause. So anymore improvement that I can do to speed up this query? The table that contains most data is the eav which have around 111276 rows/records
SELECT SQL_CALC_FOUND_ROWS eav.entid,
ent.entname
FROM eav,
ent,
catatt ca
WHERE eav.entid = ent.entid
AND ent.status = 'active'
AND eav.status = 'active'
AND eav.attid = ca.attid
AND ca.catid = 1
AND eav.catid = 1
AND ( ca.canviewby <= 6
|| ( ent.addedby = 87
AND canviewby <= 6 ) )
AND ( ( eav.attid = 13
AND ( `char` = '693fafba093bfa35118995860e340dce' ) )
OR ( eav.attid = 3
AND `double` = 6 )
OR ( eav.attid = 45
AND ( `int` = 191 ) ) )
GROUP BY eav.entid
HAVING Count(*) >= 3
EXPLAIN output
catatt table index
eav table index
ent table index
I have simplified Your query to understand it better, removed unnecessary case from where clause, made query planning.
So check this query and put to comment results and let's debug it under my answer:
SELECT
SQL_CALC_FOUND_ROWS
eav.entid,
ent.entname
FROM
eav
INNER JOIN ent ON (eav.entid = ent.entid AND ent.status = 'active')
INNER JOIN catatt ON (eav.attid = catatt.attid AND catatt.catid = 1)
WHERE
eav.catid = 1 AND eav.status = 'active'
AND (catatt.canviewby <= 6 OR ent.addedby = 87)
AND
(
(eav.attid = 13 AND eav.`char` = '693fafba093bfa35118995860e340dce')
OR
(eav.attid = 3 AND eav.`double` = 6)
OR
(eav.attid = 45 AND eav.`int` = 191)
)
GROUP BY eav.entid
HAVING COUNT(eav.entid) > 2
+ also I see You've rarely UPDATE-ing tables (data mostly inserted to these tables) - so try to make these table's engine to be MyISAM
+ create compound indexes from combinations of: attid, char ; attid, double ; attid, int
+ take a look at mysql's configuration and tune it for better query caching and memory usage
I am trying to get this query to work in JPA
It works perfectly in mysql:
select * from order_header join order_detail where (order_header.buying_partner_id = 1 or order_header.buying_partner_id = 3) AND ((order_detail.warehouse_id = 6) or (order_header.warehouse_id = 6 and order_detail.warehouse_id is null ) ) and (order_detail.tracking_number is null or order_detail.tracking_number = '') and order_detail.canceled != 1 and (order_header.order_num is NOT NULL and order_header.order_num != '') and order_header.timestamp > '2017-01-24 08:33:00.096' group by order_header.order_num order by order_header.comment DESC;
Results are returned.
JPA Query:
Select h FROM OrderHeader h JOIN h.orderDetails d WHERE ( h.buyingPartner.id = 1 or h.buyingPartner.id = 3 ) AND ( (d.warehouse.id =6) OR ( h.warehouse.id =6 AND d.warehouse.id IS null ) ) AND (d.trackingNumber IS null or d.trackingNumber = '') AND d.canceled != 1 AND (h.orderNum IS NOT null AND h.orderNum != '') and h.timestamp > '2017-01-24 09:32:39.865' GROUP BY h.orderNum ORDER BY h.comment DESC
It returns nothing. No errors. Just returns nothing.
These are the exact same statements.
There must be something wrong with my JPA statement.
Select h FROM OrderHeader h JOIN h.orderDetails d WHERE ( h.buyingPartner.id = 1 or h.buyingPartner.id = 3 ) AND ( (d.warehouse.id =6) OR ( h.warehouse.id =6 AND d.warehouse.id IS null ) ) AND (d.trackingNumber IS null or d.trackingNumber = '') AND d.canceled != 1 AND (h.orderNum IS NOT null AND h.orderNum != '') and h.timestamp > '2017-01-24 09:32:39.865' GROUP BY h.orderNum ORDER BY h.comment DESC
JPA Query uses the JOIN condition when you created the relationship between entities.
For raw SQL query you have not provided that ON condition which will be included default in JPA Query.
That's the only difference I see in it.
I'm trying to select values from a database, but I need to check another value in another database .
I created this code, but only get 1 result and I don't know why:
SELECT `id` FROM `mc_region`
WHERE `is_subregion` = 'false'
AND lastseen < CURDATE() - INTERVAL 20 DAY
AND (SELECT id_region FROM mc_region_flags
WHERE flag <> 'expire'
AND id_region = mc_region.id
)
LIMIT 0, 30
What I've made wrong?
#Edit
I think I know why this code is not working. At database mc_region_flags not all records from the primary database has flag.
I would like to do the following:
1º Select all records on the first database, where is not subregion and lastseen is more than 20 day
2º Check if any result on the 1st database has flag 'expire', if yes, they are not included in the result.
I cant do this in 1 only SQL Code?
#Edit2
I created this code that simulate FULL JOIN but seems that WHERE is not work
SELECT *
FROM mc_region AS r RIGHT OUTER JOIN
mc_region_flags AS f ON r.id = f.id_region
UNION ALL
SELECT * from
mc_region AS r LEFT OUTER JOIN
mc_region_flags AS f
ON r.id = f.id_region
WHERE r.is_subregion = 'false'
AND f.flag = 'exipre'
AND r.lastseen < CURDATE() - INTERVAL 20 DAY
Problems WHERE not work
f.flag is not 'expire'
f.lastseen is not > 20 days
UPDATED
SELECT *
FROM `mc_region` AS r LEFT JOIN
`mc_region_flags` AS f ON r.`id` = f.`id_region`
WHERE r.`is_subregion` = 'false' AND
r.`lastseen` < CURDATE() - INTERVAL 20 DAY AND
COALESCE(f.`flag`, '-') <> 'expire'
LIMIT 0, 30;
Before the inner nested select add :
id in (select...)