MySQL combine UPDATE and SELECT query - mysql

I have the following SELECT statement that returns data, example below:
SELECT performers.ID,
performers.Name,
COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN performers
ON deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN ( 27952, 27951, 27950, 27949, 27948 )
GROUP BY Name;
Example data returned:
ID Name CountOfDeals CountOfAliases
27952 Christine Hoberg 1 0
27951 Indian Jewelry 1 0
27952 Kinky Friedman 5 3
27949 KJ-52 1 0
27960 River Whyless 1 0
I want to combine this with the following UPDATE statement
UPDATE performers
SET RawAliasCount = CountOfAliases,
RawDealCount = CountOfDeals
WHERE ID = ?
All the values needed to run the update statement are returned in the select statement above so hopefully this should be pretty easy.
Thanks.

Use update with join:
UPDATE performers p JOIN
(SELECT performers.ID, performers.Name, COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN
performers
on deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN (27952, 27951, 27950, 27949, 27948)
GROUP BY Name
) pp
ON pp.id = p.id
SET RawAliasCount = pp.CountOfAliases,
RawDealCount = pp.CountOfDeals;

UPDATE performers
SET performers.RawAliasCount = count_table.CountOfAliases, performers.RawDealCount = count_table.CountOfDeals
FROM performers
INNER JOIN
(
SELECT
performers.ID, performers.Name, COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN performers on deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN (27952, 27951, 27950, 27949, 27948)
GROUP BY Name
) count_table
ON count_table.ID = performers.ID;
When this type of question is asked, thank you to put the tables schema.
edit : sorry, it's sql-server syntax.

Related

Get all applications where count of positions more then 1

I have 2 tables
LoanApplications (Id, Name, CreationDate, LoanApplicationStatusId)
Positions(Id, Name, CreationDate, LoanApplicationId)
I need to find all loan applications that have more than 1 position and update LoanApplicationStatusId to 2
I write code to get these LoanApplications like this
SELECT e.Id, count(Name) FROM LoanApplications e
INNER JOIN Positions d ON e.Id=d.LoanApplicationId
GROUP BY e.Id
HAVING COUNT(Name)>1
But I don't understand how to make an update now.
Can you help me?
Straight ahead would be a simple subselect
UPDATE LoanApplications l
SET LoanApplicationStatusId = 2
where (select count(1) from Positions p where p.LoanApplicationId = l.id) > 1
Simply select id of apps which have more than one row, and use it in UPDATE as a condition
UPDATE LoanApplications
JOIN ( SELECT LoanApplicationId
FROM Positions
GROUP BY LoanApplicationId
HAVING COUNT(LoanApplicationId) > 1 ) multi_positional ON id = LoanApplicationId
SET LoanApplicationStatusId = 2
Unsafe query: 'Update' statement without 'where' updates all table rows at once Got this stuff – Eugene Sukh
Convert this query to
UPDATE LoanApplications
JOIN ( SELECT LoanApplicationId
FROM Positions
GROUP BY LoanApplicationId
HAVING COUNT(LoanApplicationId) > 1 ) multi_positional
SET LoanApplicationStatusId = 2
WHERE LoanApplications.id = multi_positional.LoanApplicationId

How to add the number of rows of the first table to another with the condition

There are two tables:
####comments#### ####news######
#cid#news_id# #id##comm_num#
#1##1# #1###2#
#2##1# #2###1#
#3##2# #3###3#
I try to count and put the number of comments from the table 'comments' into the table 'news', but I get the wrong result. Why?
UPDATE news JOIN comments ON news.id = comments.news_id SET
news.comm_num = ( SELECT COUNT( * )
FROM comments WHERE comments.news_id > 123)
WHERE news.id > 123
'comments.news_id' = 'id' of commented news from table 'news'
I wrote a working solution for particular cases, but I can’t figure out how to make a request with a condition larger than.
UPDATE news a
SET comm_num = (SELECT COUNT(*)
FROM comments c
WHERE c.news_id = 123)
WHERE a.id = 123
Simply use a correlated subquery:
UPDATE news n
SET comm_num = (SELECT COUNT(*)
FROM comments c
WHERE c.news_id = n.id
) ;
I am not sure what the condition WHERE news.id > 123 is for.
You can get the count of total comments on a news using a Derived Table. Join this back to the news table on the news_id and update the values accordingly.
We use LEFT JOIN to handle the case where there is no comments on a news. And, Coalesce() function is used to change null to 0 (in case of no comments).
UPDATE news a
LEFT JOIN (SELECT news_id, COUNT(*) AS comm_num
FROM comments
GROUP BY news_id) b
ON b.news_id = a.id
SET a.comm_num = COALESCE(b.comm_num,0)
If you want to update only those news where id is more than 123; you can add the conditions as follows:
UPDATE news a
LEFT JOIN (SELECT news_id, COUNT(*) AS comm_num
FROM comments
WHERE news_id > 123 -- add condition to Derived Table
GROUP BY news_id) b
ON b.news_id = a.id
WHERE a.id > 123 -- add condition here also to avoid updating id <= 123
SET a.comm_num = COALESCE(b.comm_num,0)

How to make query

review table has store_idx, user_idx etc...
I want to create a query sentence that gets information about the store to which the user has bookmarked with the user_id value entered.
The query sentence I made is
select A.store_name
, A.store_img
, count(B.store_idx) as review_cnt
from board.store A
Left
Join board.review B
On A.store_idx is B.store_idx
where store_idx is (select A.store_idx from bookmark where user_id = ?)
However, nothing came out as a result.
Help me..
Please use below Query:
SELECT store_name
, store_img
, SUM(review_cnt) AS review_cnt
FROM
( SELECT DISTINCT A.store_name
, A.store_img
, CASE WHEN B.store_idx IS NULL THEN 0 ELSE 1 END AS review_cnt
FROM bookmark br
JOIN board.store A
ON A.store_idx = br.store_idx
LEFT
JOIN board.review B
ON A.store_idx = B.store_idx
WHERE br.user_id = ?
)T
The WHERE clause is obviously filtering out all rows. We can't do much about that. But your query is also lacking a GROUP BY, the table aliases can be improved, and the join condition is not correct.
So, try this version:
select s.store_name, s.store_img, count(b.store_idx) as review_cnt
from board.store s left join
board.review r
on s.store_idx = r.store_idx
where b.store_idx in (select b.store_idx
from bookmark b
where b.user_id = ?
);

INTERSECT query in MariaDB

I have a problem with this query in MariaDB language. I want to do an intersect with the same field but with two values. The problem is that i can't use the INTERSECT query.
How can I do it?? I have tried with exists and inner join but it still doesn't work.
SELECT nombre
FROM actores
WHERE codactor IN ( SELECT actor
FROM participacion
WHERE (titulo,año) IN (SELECT titulo, año
FROM peliculas
WHERE director IN (
SELECT coddirector
FROM directores d
WHERE d.nombre='Alejandro'
AND d.apellido='Amenabar')))
INTERSECT
SELECT nombre
FROM actores
WHERE codactor IN ( SELECT actor
FROM participacion
WHERE (titulo,año) IN (SELECT titulo,año
FROM peliculas
WHERE director in (
SELECT coddirector
from directores p
WHERE p.nombre='Pedro'
AND p.apellido='Almodobar')));
INTERSECT was introduced in MariaDB 10.3.0.
INTERSECT
The result of an intersect is the intersection of right and left SELECT results, i.e. only records that are present in both result sets will be included in the result of the operation.
(SELECT e_name AS name, email FROM employees)
INTERSECT
(SELECT c_name AS name, email FROM customers);
As for your query you could leave it as is.
First try it like this, to check you have all the actors. I have to add codactor in case you have actors with same name.
SELECT a.codactor, a.nombre -- add ', *' to see all columns and test query is ok.
FROM actores a
JOIN participacion p
ON a.codactor = p.actor
JOIN peliculas m
ON p.titulo = m.titulo
AND p.ano = m.ano
JOIN directores d
ON p.director = d.coddirector
WHERE (d.nombre = 'Alejandro' and d.apellido = 'Amenabar')
OR (d.nombre = 'Pedro' and d.apellido = 'Almodobar')
Then add GROUP BY to see which actor are in movies from both directors.
GROUP BY a.codactor, a.nombre
HAVING COUNT(DISTINCT coddirector) = 2

Mysql: Get all results that has all this relations

I have two tables:
objects object_features
------------- -------------------
id id
name object_id
term_id
What I want to achieve is, giving a list of features, get all objects that has all of them.
I'm trying this:
SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
This is the php code I'm using:
$feature_list = array(1,3,4,10);
$sql = 'SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('.implode(',', $feature_list).')';
This is near to what I need, but differing that it returns me any object that has any of the features given, instead of ALL the features
one option is to group by the data you want returned from object and add a having clause that counts object.id and tests to see if it is the same as the length of the array.
SELECT objects.id, objects.name
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
group by objects.id,objects.name
having count(objects.id) = 4
Cant swear to the syntax on that as I've been writing tsql recently and don't have an instance of mysql to test on.
try
'WHERE term_id = '.impode(' AND termid = ', $features_ids).')'
This will result in:
WHERE termid = 1 AND termid = 3 AND termid = 5
Actually you need a GROUP BY to group by each object and using a HAVING clause to allow only rows that have all the termids
SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
GROUP BY objects.id, objects.name
HAVING count(term_id) = 4
The SQL way of doing it would be:
SELECT objects.*
FROM objects
WHERE null not in
(
select of.object_id
from features f
left join object_features of on (f.id = of.id)
)
Assuming you have a features table with all the features.
If you need to list only certain features, you can do (check out the where condition on the subquery):
SELECT objects.*
FROM objects
WHERE null not in
(
select of.object_id
from features f
left join object_features of on (f.id = of.id)
where f.id in (1,2,3,4,5)
)