I have this query and it works perfectly but I wanted to improve it and write it without sub-query. Is this possible? Although I have tried a lot, I am not able to get correct results.
SELECT * FROM store_product
WHERE product_id NOT IN (
SELECT entity_id
FROM import_pack_file_element
WHERE entity_id IS NOT NULL
AND import_pack_file_id IN (135)
AND status = 'DONE') AND store_id = 65
You can rewrite a NOT EXISTS or NOT IN query to an anti join. I don't see any reason, however, why you'd want to do that. Anti joins are usually used on DBMS that have problems with the straight-forward [NOT] IN / [NOT] EXISTS, which should not be the case with MySQL. Anti joins are a means to defend against a DBMS weakness and come at the price of loss of readability.
SELECT sp.*
FROM store_product sp
LEFT JOIN import_pack_file_element ipfe
ON ipfe.entity_id = sp.product_id
AND ipfe.import_pack_file_id = 135
AND ipfe.status = 'DONE'
WHERE ipfe.entity_id IS NULL;
You can use LEFT JOIN and IS NULL condition
SELECT store_product.*
FROM store_product
LEFT JOIN import_pack_file_element ON store_product.product_id = import_pack_file_element.entity_id
AND import_pack_file_element.import_pack_file_id IN (135)
AND import_pack_file_element.status = 'DONE'
WHERE
import_pack_file_element.entity_id IS NULL
You could use an EXISTS clause:
SELECT *
FROM store_product sp
WHERE NOT EXISTS (SELECT 1 FROM import_pack_file_element i
WHERE i.entity_id = sp.product_id AND
import_pack_file_id = 135 AND status = 'DONE');
You can try this(but better use Subquery instead):
SELECT [table alias].*
FROM store_product [table alias]
LEFT JOIN import_pack_file_element [table alias] on [table alias].[key] = [table alias].[key]
WHERE [table alias].entity_id IS NOT NULL AND [table alias].import_pack_file_id IN(135) AND [table alias].status = 'DONE'
You can modify LEFT JOIN part and WHERE part as your needs.
also this : [key] to your table key, [table alias] to your table alias.
and also this, u can replace IN(135) and use equals sign =, IN is use for more than one element that u need to compare or validate.
and here the reference :
LEFT JOIN
I don't have the full knowledge about your table design but this might work:
SELECT * FROM store_product x LEFT OUTER JOIN import_pack_file_element y
ON x.product_id = y.entity_id
WHERE x.product_id IS NULL
AND import_pack_file_id = 135
AND status = 'DONE'
Related
select `tbl_users`.`username`, `tbl_users`.`users_id`, `tbl_users`.`profile_picture`,
(select count(users_id) from tbl_movies_comments where users_id = `tbl_users`.`users_id`) as UsersCommentsCount,
(select count(users_id) from tbl_movies_reviews where users_id = `tbl_users`.`users_id`) as UserReviewsCount
left join `tbl_movies_comments` on `tbl_users`.`users_id` = `tbl_movies_comments`.`users_id`
left join `tbl_movies_reviews` on `tbl_users`.`users_id` = `tbl_movies_reviews`.`users_id`
group by `tbl_users`.`username`, `tbl_users`.`users_id`, `tbl_users`.`profile_picture`, `tbl_movies_comments`.`users_id`, `tbl_movies_reviews`.`users_id`
Your statement is really bad formatted. This is one reason why its hard to debug code...
....
(
SELECT
Count(users_id)
FROM
tbl_movies_reviews
WHERE
users_id = tbl_users.users_id
) AS userreviewscount
FROM yourtablename <<<--- Missing
left JOIN tbl_movies_comments
ON tbl_users.users_id = tbl_movies_comments.users_id
....
Use tools like HeidiSQL or an online Syntax formatter/checker to avoid such situations
There is no FROM clause in your query.
SELECT ...
FROM `tbl_users`
LEFT JOIN ...
This is mostly a SQL syntax / SQL capability question. Why does the following query NOT work:
SELECT * from
(
select m.*, p.type,
from multipliers m
inner join pushes p
on m.push_id = p.id
where p.type = 'CONSTANT'
) AS res1 where res1.push_id = (
select max(push_id) from res1
);
when the following completes without issue:
SELECT * from
(
select m.*, p.type,
from multipliers m
inner join pushes p
on m.push_id = p.id
where p.type = 'CONSTANT'
) AS res1 where res1.push_id = (
select max(push_id) from
(
select m.push_id
from multipliers m
inner join pushes p
on m.push_id = p.id
where p.type = 'CONSTANT'
) AS res2
);
Per the MySQL 5.7 documentation:
Derived tables cannot be correlated subqueries, or contain outer references or references to other tables of the same SELECT.
In other words, you can't reference a derived table in a subquery. The documentation doesn't state this, but it likely acts this way because of an OOO issue since the derived table isn't necessarily processed before the subquery. In MySQL 8.0 you will be able to use a Common Table Expression or CTE, which basically lets you define a reusable derived table before your query, but until then use your second approach.
The first query doesn't work because the selected column doesn't exist. At least if you want to reuse it, it should be res.push_id, anyway it's better to use CTE as Jarlh said in his comment.
WITH
myCte AS ( select m.*, p.type,
from multipliers m
inner join pushes p
on m.push_id = p.id
where p.type = 'CONSTANT')
SELECT * FROM myCte
WHERE myCte.push_id = (SELECT MAX(push_id) FROM myCte)
The error in the 1st query is that a table alias (correlation name) can't be used as a table expression in a FROM.
A table alias with a dot & column identifies a column of a table. (In the predicate logic or relational calculus sense a table alias is a subrow-valued variable.)
I want to use subquery inside of IFNULL statement
SELECT t.col1
, IFNULL(t.col2, (SELECT an.col_11
FROM another_table an
WHERE an.col1 = t.col5)) as alias_name
, t.col3
FROM table t;
In IFNULL statement second expression should be subquery.
Please give me proper syntax
My actual query is
SELECT u.username, up.gender, d.name, desg.name,
IFNULL(up.creative_lead_id,
(SELECT au.username FROM auth_user au
WHERE au.id=up.creative_lead_id)) as creative_lead, up.image
FROM user_profile up, department d, designation, auth_user
WHERE up.department_id=d.id
AND up.designation_id = desg.id up.auth_uesr_id = u.id;
This query is giving syntax error because of IFNULL statement.
You can rewrite your query with join,Correlated query will execute for each row in your table and it might affect the performance
SELECT
t.col1,
IFNULL(t.col2, an.col_11) AS alias_name,
t.col3
FROM
`table` t
LEFT JOIN another_table an
ON an.col1 = t.col5
Don't use a subquery for this situation, try a query like that instead (use of jointure):
SELECT t.col1
,IFNULL(t.col2, an.col_11) AS alias_name
,t.col3
FROM your_table t
LEFT JOIN another_table an ON an.col1 = t.col5
In your full query, your using twice up.creative_lead_id for your IFNULL clause (once as first parameter and then in the subquery). That make no sense because if the first param is NULL, your subquery will return no result!
In order to show you the principe that will solve your problem, i just replaced the first param by a fictive one that i called up.creative_lead. This fictive column is the name of the creative lead stored in your table user_profile and if this value is null, i'm looking to the username of the user corresponding to creative_lead_id.
Here is the full query that'll solve your problem with the correction mentioned above:
SELECT u.username
,up.gender
,d.name
,desg.name
,IFNULL(up.creative_lead, cl.username) AS creative_lead
,up.image
FROM user_profile up
INNER JOIN department d ON d.id = up.department_id
INNER JOIN designation desg ON desg.id = up.designation_id
INNER JOIN auth_user u ON u.id = up.auth_user_id
INNER JOIN auth_user cl ON cl.id = up.creative_lead_id
Notice that i changed the syntax of your query, it's highly recommended to avoid the use of old syntax for jointures (use explicit JOIN clause instead).
Hope this will help you.
I have the following SQL statement
SELECT be.*, it.order_number
FROM songs AS be
INNER JOIN
(
SELECT song_id, order_number
FROM items
WHERE order_status = 1
) it
ON be.id = it.song_id
INNER JOIN orders AS or
ON it.order_number = or.order_number
WHERE be.active = 0
I can't seem to understand why this statement does not produce any results. When I remove the following line;
INNER JOIN orders AS or
ON it.order_number = or.order_number
It seems to produce results, and I know that the order_number does exist in the orders table - so it's clearly incorrect syntax but i'm not sure where to go from here? Appreciate the help.
The problem in this particular instance is that the or in the query is a reserved word. You can use that if you wish, but you'll have to quote it, like so
SELECT be.*, it.order_number
FROM songs AS be
INNER JOIN
(
SELECT song_id, order_number
FROM items
WHERE order_status = 1
) it
ON be.id = it.song_id
INNER JOIN orders AS "or"
ON it.order_number = "or".order_number
WHERE be.active = 0
Generally though, for readability, I'd avoid such names. If you have to quote it or escape it, it's probably a bad name.
I am trying to create an update query and making little progress in getting the right syntax.
The following query is working:
SELECT t.Index1, t.Index2, COUNT( m.EventType )
FROM Table t
LEFT JOIN MEvents m ON
(m.Index1 = t.Index1 AND
m.Index2 = t.Index2 AND
(m.EventType = 'A' OR m.EventType = 'B')
)
WHERE (t.SpecialEventCount IS NULL)
GROUP BY t.Index1, t.Index2
It creates a list of triplets Index1,Index2,EventCounts.
It only does this for case where t.SpecialEventCount is NULL. The update query I am trying to write should set this SpecialEventCount to that count, i.e. COUNT(m.EventType) in the query above. This number could be 0 or any positive number (hence the left join). Index1 and Index2 together are unique in Table t and they are used to identify events in MEvent.
How do I have to modify the select query to become an update query? I.e. something like
UPDATE Table SET SpecialEventCount=COUNT(m.EventType).....
but I am confused what to put where and have failed with numerous different guesses.
I take it that (Index1, Index2) is a unique key on Table, otherwise I would expect the reference to t.SpecialEventCount to result in an error.
Edited query to use subquery as it didn't work using GROUP BY
UPDATE
Table AS t
LEFT JOIN (
SELECT
Index1,
Index2,
COUNT(EventType) AS NumEvents
FROM
MEvents
WHERE
EventType = 'A' OR EventType = 'B'
GROUP BY
Index1,
Index2
) AS m ON
m.Index1 = t.Index1 AND
m.Index2 = t.Index2
SET
t.SpecialEventCount = m.NumEvents
WHERE
t.SpecialEventCount IS NULL
Doing a left join with a subquery will generate a giant
temporary table in-memory that will have no indexes.
For updates, try avoiding joins and using correlated
subqueries instead:
UPDATE
Table AS t
SET
t.SpecialEventCount = (
SELECT COUNT(m.EventType)
FROM MEvents m
WHERE m.EventType in ('A','B')
AND m.Index1 = t.Index1
AND m.Index2 = t.Index2
)
WHERE
t.SpecialEventCount IS NULL
Do some profiling, but this can be significantly faster in some cases.
my example
update card_crowd as cardCrowd
LEFT JOIN
(
select cc.id , count(1) as num
from card_crowd cc LEFT JOIN
card_crowd_r ccr on cc.id = ccr.crowd_id
group by cc.id
) as tt
on cardCrowd.id = tt.id
set cardCrowd.join_num = tt.num;