I'm not sure if this is possible but what I like to do is the following:
I have a list of id's stored in a table
I have a list of numbers I have already
I want 1 in statement that joins the 2 eg,
SELCET * from `table1` where `ID` IN ( (SELECT `id` from `table2` where `columnA` = 'yes') or (1,2,3,4))
but I am not sure how I can combine the two results in one statement.
The easiest way would probably be to have two separate in conditions:
SELCET *
FROM `table1`
WHERE `id` IN (SELECT `id` FROM `table2` WHERE `columnA` = 'yes') OR
`id` IN (1,2,3,4)
Related
So let's say that I have a query:
SELECT `id` FROM `tablename`
This will returns some IDs in rows. Now I want to use these IDs to get data from another table with the 'IN' function.
SELECT `somecol` FROM `anothertable` WHERE `parent` IN ( {IDs here} )
I could do this with PHP using 2 different queries. But I wanted to know how or can it be done with MySQL alone, using only one query?
Use exists:
SELECT somecol
FROM anothertable a
WHERE EXISTS (
SELECT * FROM tablename t WHERE t.ID = a.parent
);
Just pass in your first query inside you second query:
SELECT
`somecol`
FROM
`anothertable`
WHERE
`parent`
IN (SELECT `id` FROM `tablename`)
Consider a table table1 and its corresponding lookup table table2:
`table1`
columns: col1 | id
number of rows: ~2Mi
`table2`
columns: id <primary key> | col2
number of rows: ~1Mi
Since there are several ids in table2 which are not being used in table1, they can be deleted. This can be done with the following query:
DELETE FROM `table2` WHERE `id` IN (
SELECT * FROM (
SELECT `table2`.`id` FROM `table2`
LEFT JOIN `table1`
ON `table1`.`id` = `table2`.`id`
WHERE `table1`.`id` IS NULL
) AS p
)
However, this query is very slow (~100 rows per minute).
Question
Why this query is so slow? How to improve it?
You could rewrite it as:
DELETE FROM `table2`
WHERE NOT EXISTS(SELECT 1 FROM `table1` WHERE `table1`.id = `table2`.id);
Adding index on table2(id) and table1(id) will also help.
We're trying to calculate the rank of contestants for a specific contest, using the following select query. The GROUP_CONCAT workaround is actually a solution that was offered here on SO for a similar question.
However, as we added more conditions the query got long, untidy and is not DRY, I think as we have to repeat the same conditions for the GROUP_CONCAT subquery.
How can it be optimized? Or would a solution like programmatically calculate ranks and check conditions then populate the database, be the best solution in this case?
SELECT *,
-- Get the rank of contestants
FIND_IN_SET(`id`, (
SELECT GROUP_CONCAT(`id` ORDER BY `points` DESC, `created`)
FROM `contestants` `c2`
-- The following query is exactly the same as the on in the main query bellow.
WHERE `contest_id`=:contest_id
AND EXISTS (
SELECT `user_id`
FROM `item`
WHERE `user_id`=`c2`.`user_id`
AND `product_id` IN (
SELECT `id`
FROM `product`
WHERE `price`<=:max_price
AND `available`=:available
)
)
AND `state`=:state
-- ---------------------------------------------------------------------------
)
) AS `rank`
FROM `contestants`
-- ---------------------------------------------------------------------------
WHERE `contest_id`=:contest_id
AND EXISTS (
SELECT `user_id`
FROM `item`
WHERE `user_id`=`c2`.`user_id`
AND `product_id` IN (
SELECT `id`
FROM `product`
WHERE `price`<=:max_price
AND `available`=:available
)
)
AND `state`=:state
-- ---------------------------------------------------------------------------
ORDER BY `rank` ASC
LIMIT 10
I am trying to select two data sets from the same table, instead of doing two queries I am trying to select them both in one call.
First of all I want to:
SELECT COUNT(*) AS `total` FROM `Messages` WHERE `id` = '1';
and the second is:
SELECT COUNT(*) AS `total_read` FROM `Messages` WHERE `id` = '1' AND `read` = '1';
Is there anyway to do this in one query?
SELECT
COUNT(*) total,
SUM(IF(read='1',1,0)) total_read
FROM Messages
WHERE id='1';
I need to merge two queries:
First query:
SELECT `p`.`name`, `posts`.*
FROM `polls` `p`, `posts`
WHERE `p`.`id` = `posts`.`guid`
AND `first` = {$id}
AND `text` LIKE ?
with... second query:
SELECT SUM(`deleted` = 0) AS 'posts'
FROM `posts`
WHERE `first`
NOT IN
(
SELECT `id`
FROM `posts`
WHERE `deleted` = 1
AND `first` = `id`
) AND `first` = {$fid}
Is there any chance to merge them?
You can use a UNION. You'll have to make them return the same columns though. The second query will have to return blank values for everything else.
I don't know what the query is trying to achieve, or what kind of results the queries produce. I think query 1 searches for posts like text, query 2 searches for deleted posts by ID. I've done a jig around, it should work if both queries generate the same amount of rows.
Changes:
1 You'd need to change the AS in the second query to a unique name (so here, posts_sum).
2 I've also removed the second ID join.
Check it out:
SELECT `p`.`name`, `posts`.*, SUM(`deleted` = 0) AS 'posts_sum'
FROM `polls` `p`, `posts`
WHERE `p`.`id` = `posts`.`guid`
AND `first` = {$id}
AND `text` LIKE ?
AND `first`
NOT IN
(
SELECT `id`
FROM `posts`
WHERE `deleted` = 1
AND `first` = `id`
)