How do you store result row count in nested SELECT? - mysql

I have a MySQL query where I have a nested SELECT that returns an array to the parent:
SELECT ...
FROM ...
WHERE ... IN (SELECT .... etc)
I would like to store the number of returned results (row count) from the nested SELECT, but doing something like IN (SELECT count(...), columnA) does not work, as the IN expects just one result.
Is there a way to store the returned result count for later use within the parent statement?

You're probably going to have to select the results of your nested statement into a temporary table. Then you can do an IN and a count on it later. I'm more familiar with MS-SQL, but I think you should be able to do it like this:
CREATE TEMPORARY TABLE tmp_table AS
SELECT something
FROM your_table;
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
If that doesn't work, you may have to provide full details to the temporary table creation statement as you would with a normal "CREATE TABLE". See here in the MySQL manual, and here for a similar example.
CREATE TEMPORARY TABLE tmp_table
(
tableid INT,
somedata VARCHAR(50)
);
INSERT INTO tmp_table
SELECT ...
FROM ...
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
Rich

You mentioned in your comment that your query look like this:
SELECT
tabA.colA,
tabA.colB
FROM tabA
WHERE tabA.colA IN ( SELECT tabA.colA FROM tabA WHERE tabA.colB = 1 )
I might be missing something, but you don't need a subquery for this. Why don't you do it in a regular where condition:
SELECT
tabA.colA,
tabA.colB,
FROM tabA
WHERE tabA.colB = 1

You can use IN predicate for multiple columns like this:
SELECT *
FROM table
WHERE (col1, col2) IN
(
SELECT col3, col4
FROM othertable
)
If you want to select COUNT(*) along with each value, use this:
SELECT colA, colB, cnt
FROM (
SELECT COUNT(*) AS cnt
FROM tabA
WHERE colB = 1
) q,
tabA
WHERE colB = 1

Related

sub query and common table expression

Hi I want to understand how to structure query in subquery vs common table expression: See example below.
Write a query to count deduped records in the health.user_logs table
Approach 1: use sub query: select count statement is in the beginning
SELECT COUNT(*)
FROM (
SELECT DISTINCT *
FROM health.user_logs
) AS subquery;
Approach 2: use common table expression: select count statement is in the end?
WITH deduped_logs AS (
SELECT DISTINCT *
FROM health.user_logs
)
SELECT COUNT(*)
FROM deduped_logs;
When to decide if the select count statement should be in the beginning or in the end?
Most often this is about personal preferences, i.e. what you like better and consider more readable.
SELECT ...
FROM
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
JOIN another_table ON ...
and
WITH
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
SELECT ...
FROM subquery
JOIN another_table ON ...
are equivalent and one is as good as the other. One advantage with the WITH clause is that you can access the same subquery more than once:
WITH
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
SELECT ...
FROM subquery s1
JOIN subquery s2 ON s2.type = s1.type AND s2.id < s1.id
Another advantage is that you can build your query step by step without nesting subquery in subquery (at least not visibly), so the query may be considered more readable:
WITH all_jobs AS (...)
, technical_jobs AS (... FROM all_jobs ...)
, well_paid_technical_jobs AS (... FROM technical_jobs ...)
SELECT *
FROM well_paid_technical_jobs
WHERE ...
vs.
SELECT *
FROM
(
SELECT ...
FROM
(
SELECT ...
FROM
(
...
) all_jobs
WHERE ...
) technical_jobs
WHERE ...
) well_paid_technical_jobs
WHERE ...

from the sample database , How could I make a query where I could search all the region ( region id) where Kivuto Id is duplicated?

I need to fetch the 3 lines as highlighted in the result with green i.e separate region id but same kivuto id.I need to rectify such products so that I could correct the kivuto id's
Try this.
select * from table_name
where kivuto_id in (
select email from table_name
group by kivuto_id
having count(*) > 1
)
You can refer to this as well: Find rows that have the same value on a column in MySQL
You can simply use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.kivuto_id = t.kivuto_id and
t2.region_id <> t.region_id
);
For performance, you want an index on (kivuto_id, region_id).

Number of different records (rows) in a table

quite often I have to count then number of different records in a table. However, in MySQL neither
select count(distinct *) from t;
nor
select count(distinct t.*) from t;
work. I know that I can work around that by
select count(*) as countdistinctrows
from (
select distinct * from t
) x;
but this is ugly. Is there really no way do ask for the number of distinct rows? By the way,
select distinct count(*) from t;
is not the answer since then distinct is applied to the number of rows in the table and thus gives the same as
select count(*) from t;
If you don't want to use this:
select count(*) as countdistinctrows
from (
select distinct * from t
) x;
the only alternative I can think of is to specify all the column names manually:
select count(distinct id, col1, col2, col3, ...)
from t;

JOIN / UNION SELECT all rows from two tables with different number of columns

I am trying to join or union the results of two differently structured tables, order them by a their common pubdate column, but get an error message:
The used SELECT statements have a different number of columns
SELECT * FROM news WHERE published='1' AND image!='' AND featured='1'
JOIN
SELECT * FROM videos WHERE published='1'
ORDER BY pubdate DESC
How can I edit my query so that I can run my fetch array and retrieve the corresponding rows afterwards (the rows to be fetched is then decided on another common row that both tables share)?
You can UNION ALL tables with a different number of columns by adding the missing columns in the select list. I mean, suppose you have:
SQL> create table one ( c1 integer , c2 integer, c3 integer ) ;
SQL> create table two ( c1 integer , c2 integer ) ;
The following UNION ALL won't work:
SQL> select * from one union all select * from two ;
[mysqld-5.5.27]The used SELECT statements have a different number of columns
But this one is ok:
SQL> select * from one union all select *, null from two ;
Note we did add NULL for the missing (c3) column on table two. You can add whatever you want...
Since you not provided sample data, we can't suggest you correct way what and how to use, but I noticed that:
With JOIN you have incorrect syntax. Should be like:
SELECT *
FROM tbl1 t1
INNER JOIN tbl2 t2 ON t1.Id = t2.Id
If you want to use UNION - order of columns and number of columns should match in both tables, so you have to provide column names in both tables, in following:
SELECT Col1, Col2, Coln
FROM tbl1
UNION
SELECT Col1, Col2, Coln
FROM tbl2

Using the result of one query inside another query (MySQL)

I need to get a subset of one of my tables, and then use these id's in another query, is this possible?
Ideally, I need to use the result of this query:
SELECT id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1
inside this query:
UPDATE table
SET col1 = CONCAT(col1, '_1')
WHERE id IN (ABOVE_QUERY)
I think you are looking for something like this:
UPDATE
table INNER JOIN (SELECT MAX(id) as m_id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1) t1
ON table.id = t1.m_id
SET col1 = CONCAT(col1, '_1')
In MySQL you need to use a JOIN because you aren't allowed to update a table referenced in a subquery. And you probably need to use an aggregated function on the ID returned by your subquery.