mysql update subquery not working - php

mysql update syntax doesn't seem to work when I added the subquery.
Are there restrictions on subqueries on update syntax?
doesn't work:
update books set imagename ='name'
where book_ID='(select book_ID from books order by book_ID desc limit 1)';
works:
update books set imagename ='name'
where book_ID='101';

MySQL does have limits on subqueries using the table being updated. So yours is not allowed:
update books
set imagename ='name'
where book_ID = (select book_ID from books order by book_ID desc limit 1);
Instead, you can do:
update books
set imagename ='name'
order by book_ID desc
limit 1;
Here is the explanation in the documentation:
In general, you cannot modify a table and select from the same table
in a subquery. For example, this limitation applies to statements of
the following forms:
DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS _t ...);
Here the result from the subquery in the FROM clause is stored as a temporary table, so the relevant rows in t have already been
selected by the time the update to t takes place.

Try This query.
Update books
Set imagename = name"
Where book_ID In (
Select T1.book_ID
From books As T1
Where T1.book_ID = '101'
)

Related

Select most common value? [duplicate]

How can I find the most frequent value in a given column in an SQL table?
For example, for this table it should return two since it is the most frequent value:
one
two
two
three
SELECT
<column_name>,
COUNT(<column_name>) AS `value_occurrence`
FROM
<my_table>
GROUP BY
<column_name>
ORDER BY
`value_occurrence` DESC
LIMIT 1;
Replace <column_name> and <my_table>. Increase 1 if you want to see the N most common values of the column.
Try something like:
SELECT `column`
FROM `your_table`
GROUP BY `column`
ORDER BY COUNT(*) DESC
LIMIT 1;
Let us consider table name as tblperson and column name as city. I want to retrieve the most repeated city from the city column:
select city,count(*) as nor from tblperson
group by city
having count(*) =(select max(nor) from
(select city,count(*) as nor from tblperson group by city) tblperson)
Here nor is an alias name.
Below query seems to work good for me in SQL Server database:
select column, COUNT(column) AS MOST_FREQUENT
from TABLE_NAME
GROUP BY column
ORDER BY COUNT(column) DESC
Result:
column MOST_FREQUENT
item1 highest count
item2 second highest
item3 third higest
..
..
For use with SQL Server.
As there is no limit command support in that.
Yo can use the top 1 command to find the maximum occurring value in the particular column in this case (value)
SELECT top1
`value`,
COUNT(`value`) AS `value_occurrence`
FROM
`my_table`
GROUP BY
`value`
ORDER BY
`value_occurrence` DESC;
Assuming Table is 'SalesLT.Customer' and the Column you are trying to figure out is 'CompanyName' and AggCompanyName is an Alias.
Select CompanyName, Count(CompanyName) as AggCompanyName from SalesLT.Customer
group by CompanyName
Order By Count(CompanyName) Desc;
If you can't use LIMIT or LIMIT is not an option for your query tool. You can use "ROWNUM" instead, but you will need a sub query:
SELECT FIELD_1, ALIAS1
FROM(SELECT FIELD_1, COUNT(FIELD_1) ALIAS1
FROM TABLENAME
GROUP BY FIELD_1
ORDER BY COUNT(FIELD_1) DESC)
WHERE ROWNUM = 1
If you have an ID column and you want to find most repetitive category from another column for each ID then you can use below query,
Table:
Query:
SELECT ID, CATEGORY, COUNT(*) AS FREQ
FROM TABLE
GROUP BY 1,2
QUALIFY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY FREQ DESC) = 1;
Result:
Return all most frequent rows in case of tie
Find the most frequent value in mysql,display all in case of a tie gives two possible approaches:
Scalar subquery:
SELECT
"country",
COUNT(country) AS "cnt"
FROM "Sales"
GROUP BY "country"
HAVING
COUNT("country") = (
SELECT COUNT("country") AS "cnt"
FROM "Sales"
GROUP BY "country"
ORDER BY "cnt" DESC,
LIMIT 1
)
ORDER BY "country" ASC
With the RANK window function, available since MySQL 8+:
SELECT "country", "cnt"
FROM (
SELECT
"country",
COUNT("country") AS "cnt",
RANK() OVER (ORDER BY COUNT(*) DESC) "rnk"
FROM "Sales"
GROUP BY "country"
) AS "sub"
WHERE "rnk" = 1
ORDER BY "country" ASC
This method might save a second recount compared to the first one.
RANK works by ranking all rows, such that if two rows are at the top, both get rank 1. So it basically directly solves this type of use case.
RANK is also available on SQLite and PostgreSQL, I think it might be SQL standard, not sure.
In the above queries I also sorted by country to have more deterministic results.
Tested on SQLite 3.34.0, PostgreSQL 14.3, GitHub upstream.
Most frequent for each GROUP BY group
MySQL: MySQL SELECT most frequent by group
PostgreSQL:
Get most common value for each value of another column in SQL
https://dba.stackexchange.com/questions/193307/find-most-frequent-values-for-a-given-column
SQLite: SQL query for finding the most frequent value of a grouped by value
SELECT TOP 20 WITH TIES COUNT(Counted_Column) AS Count, OtherColumn1,
OtherColumn2, OtherColumn3, OtherColumn4
FROM Table_or_View_Name
WHERE
(Date_Column >= '01/01/2023') AND
(Date_Column <= '03/01/2023') AND
(Counted_Column = 'Desired_Text')
GROUP BY OtherColumn1, OtherColumn2, OtherColumn3, OtherColumn4
ORDER BY COUNT(Counted_Column) DESC
20 can be changed to any desired number
WITH TIES allows all ties in the count to be displayed
Date range used if date/time column exists and can be modified to search a date range as desired
Counted_Column 'Desired_Text' can be modified to only count certain entries in that column
Works in INSQL for my instance
One way I like to use is:
select *<given_column>*,COUNT(*<given_column>*)as VAR1 from Table_Name
group by *<given_column>*
order by VAR1 desc
limit 1

How can I order by count in mysql when the count need data to calculate from this select statement?

Look at my code, I want the select statement order by the count percentage after I fetch the data from this select statement, obviously, it's not logical. What can I do? Help, appreciate.
<?php
//myslq connection code, remove it because it's not relate to this question
$stm =$db->prepare("SELECT id ,term_count, COUNT(user_id) as count FROM sign WHERE term IN (:term_0,:term_1) GROUP BY user_id ORDER by count DESC");
//trying replace order by count with $combine_count, but it's wrong
$term_0="$term[0]";
$term_1="$term[1]";
$stm->bindParam(":term_0", $term_0);
$stm->bindParam(":term_1", $term_1);
stm->execute();
$rows = $stm->fetchALL(PDO::FETCH_ASSOC);
foreach ($rows as rows) {
$count=$rows['count'];
$term_count_number=$rows['term_count'];
$count_percentage=round(($count/$count_user_diff)*100);
$count_key_match=round(($count/$term_count_number)*100);
$combine_count=round(($count_percentage+$count_key_match)/2);
//issue is here, I want the select statement order by $combine_count
}
?>
SELECT id ,term_count, COUNT(user_id) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
Since "count" is a function, it would be better to put backtics around the non-function "counts", as done above.
GROUP BY should list the field not aggregated. Otherwise, it does not know which id and term_count to fetch. So, depending on what you are looking for,
Either do
SELECT user_id, COUNT(*) as `count` -- I changed this line
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
or do
SELECT id ,term_count, COUNT(*) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY id ,term_count -- I changed this line
ORDER by `count` DESC");
SQL Syntax Logic
SELECT column1, count(column1) AS amount
FROM table_name
GROUP BY column1
ORDER BY amount DESC
LIMIT 12

get table name from count query

How do you get table name from count query, I have multiple queries and I need to get table name from the query results, here is my query
$myquery = "select count(tb_id) as num_rows from table1; select count(tb1_id) from table2...";
if (myqli_multi_query($connection, $myquery){
..
$row = mysqli_fetch_assoc($result);
$num_rows = $row["num_rows"];
..
}
The query is working fine as I can get the number of rows, but I am unable to link the table name to the number of rows (result)
I have tried this, which executes without error, but unable to get the table name still
select count(tb_id) as num_rows, 'table1' as TableName from table1
You could put an identifier into your query you can refer to later.
$myquery = "select 'table1' as tablename, count(tb_id) as num_rows from table1;
select 'table2' as tablename, count(tb1_id) as num_rows from table2;"
// and so on
You can try mysqli_fetch_field
mysqli_fetch_field($result)->table;
Just add it in to the select or the column name.
Column name:
select count(tb_id) as table1_count from table1; select count(tb1_id) as table2_count from table2.
OR sep column:
(select count(tb_id) as num_rows, 'table1' as tablename from table1)
UNION
(select count(tb1_id), 'table2' from table2...)
UNION.... etc
Edited to add: you are returning sep resultsets; consider UNION above for a single resultset.

MySQL query record with max value in a specific column

I know that this must be a very basic question, but I've not found an answer.
As the title says, I would like the query the record that holds the max value of a specific column.
I use the following code to achieve that:
SELECT * FROM `table_name` ORDER BY `column_with_specific_max_value` DESC LIMIT 1
I would like to know if there is an other way to achieve the same result (more parsimonious)? I know that SQL has a function MAX(column) but it's not working the way I want. I tried this:
SELECT * FROM `table_name` WHERE `column_with_specific_max_value`=MAX(`column_with_specific_max_value`)
and this:
SELECT *, MAX(`column_with_specific_max_value`) FROM `table_name`
What happen if the column_with_specific_max_value has 2 rows with the same max value? will it return both rows?
What about?
select * from table1
where score in (select max(score) from table1)
Or even without a max:
select * from table1
where score >= all (select score from table1)
Any of those WILL return all rows with the max value. You can play with it here.
If your table has an auto-increment column to work with, you could do something like...
select
YT3.*
from
( select
MAX( YT2.AutoIncColumn ) as ReturnThisRecordID
from
( select max( YT1.WhatColumn ) as MaxColumnYouWant
from YourTable YT1 ) JustMax
Join YourTable YT2
on JustMax.MaxColumnYouWant = YT2.WhatColumn ) FinalRecord
JOIN YourTable YT3
on FinalRecord.ReturnThisRecordID = YT3.AutoIncColumn
I would also ensure this is a column that SHOULD have an index on it, otherwise, you'll always be doing a table scan.

MYSQL working slowly as query with subquery than 2 queries (+php)

I have table (about 80'000 rows), looks like
id, parentId, col1, col2, col3...
1, null, 'A', 'B', 'C'
2, 1, ...
3, 1, ...
4, null, ...
5, 4, ...
(one level parent - child only)
and I need get all dependent rows -
SELECT ...
FROM table
WHERE id = :id OR parentId = :id OR id IN (
SELECT parentId
FROM table
WHERE id = :id
)
but why this request working slowly instead 2 request - if I get parentId on php first?
$t = executeQuery('SELECT parentId FROM table WHERE id = :Id;', $id);
if ($t) {
$id = $t;
}
$t = executeQuery('SELECT * FROM table WHERE id = :id OR parentId = :id ORDER BY id;', $id);
PS: max depends rows < 70
PPS:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY product ALL PRIMARY,parentId NULL NULL NULL 73415 Using where
2 DEPENDENT SUBQUERY product const PRIMARY,parentId PRIMARY 4 const 1
Change the IN for an equal =
SELECT ...
FROM table
WHERE id = :id OR parentId = :id OR id = (
SELECT parentId
FROM table
WHERE id = :id
)
or change it to a join:
SELECT ...
FROM table
inner join (
SELECT parentId
FROM table
WHERE id = :id
) s on s.parentID = table.id or s.parentID = table.parentID
Well, in the first case, MySQL need to create an intermediate result, store it in memory and then iterate over it to find all the relevant id in the table. In the second way, assuming you correctly created an index on id and parent id, it simply go straigth to the index, find the relevant rows, and send you back the result immediately.
UNION works faster for this case
this allows first query to user UNION INDEX and second just uses inner join, then merges results.
SELECT *
FROM `table`
WHERE id = :id OR parentId = :id
UNION
SELECT t1.*
FROM `table` t1 JOIN `table` t2 ON t2.parentId = t1.id AND t2.id = :id
An EXPLAIN might shed some more light on the problem for you.
Look into EXISTS, or rewriting your query as a JOIN.
It's a long shot but in first case you have "IN" statement of the WHERE part of the query. Maybe MySQL tries to optimize the query as if there would be multiple options and in the second case there is no IN part, so the compiled query is more straight forward for the database - thus utilizing the indexes in better manner.
Basically for 2 queries on the same connection the overhead of performing the queries should be minimal and irelevant in this case. Also subqueries in general are not very optimizable by the query parser. Try using JOIN instead (if possible).

Categories