Select Count from Two Tables = Multiplication in SQL? - mysql

I randomly tried running a query like:
select count(*) from table1, table2
The result was essentially multiplication of the actual row count of the two tables, i.e. the result was 645792 rows based on the fact that table1 had 868 rows, and table2 had 744 rows.
Is this an expected behaviour, I checked out the documentation but could not get any better understanding of this behaviour.

This is your from clause:
from table1, table2
This is equivalent to:
from table1 cross join table2
This is a cartesian product of both tables, which generates a resultset containing 868 * 744 rows. Then count(*) just counts the number of resulting rows, hence the result that you are getting.
If you wanted to sum the number of rows in each table, you would compute two separate counts:
select
(select count(*) from table1)
+ (select count(*) from table2) total_no_rows

Your current query:
select count(*) from table1, table2
is using the old school implicit join syntax. As there is no join criteria appearing in a WHERE clause (there is no WHERE clause), the join defaults to being a cross join. This is just the cross product between records in the two tables, which is what you are currently seeing. A better way to write your query would be:
SELECT COUNT(*)
FROM table1
CROSS JOIN table2;

'INNER JOIN and , (comma) are semantically equivalent in the absence of a join condition: both produce a Cartesian product' https://dev.mysql.com/doc/refman/8.0/en/join.html

Related

How to group only by joined table column with Doctrine?

I have one join table:
table1_id|table2_id
1|1
1|2
2|1
2|2
3|1
I need to select rows grouped by table2. But I need special grouping. In result row I want to see the following:
table1.id|grouped
1,2|1,2
3|1
I tried different ways.
Select from table1 and group by table2.id. Fail - MySql required query to be grouped my primary table as well.
Select from table2 and group by table1.id and table2.id . Fail - it selects rows from table2 separately, I want them to be concatenated as I shown in the example.
Select from table1 and group by group_concat(table2.id). But MySql does not allow to group by aggregated functions.
My example query: http://sqlfiddle.com/#!9/934b64/4. I need almost the same, but so that it will one row with values:
1,2|1,2
3|1
You are almost there.
You need to use GROUP_CONCAT in SELECT clause, not in GROUP BY clause.
SELECT table1_id,GROUP_CONCAT(table2_id) as grouped
FROM table
GROUP BY table1_id;
See the result in SQL Fiddle
For your requirement, please try the below query:
select t1.id,t1.value,
group_concat(t2.id) as grouped_ids,
group_concat(t2.value) as grouped_values
from table1 t1
join joined_table jt on jt.id1 = t1.id
join table2 t2 on t2.id = jt.id2
group by t1.id,t1.value
Result in SQL Fiddle

Explaining MySQL query with multiple tables listed in FROM

a, b are not directly related.
What does a,b have to do with the results?
select * from a,b where b.id in (1,2,3)
can you explain sql?
Since you haven't specified a relationship between a and b, this produces a cross product. It's equivalent to:
SELECT *
FROM a
CROSS JOIN b
WHERE b.id IN (1, 2, 3)
It will combine every row in a with the three selected rows from b. If a has 100 rows, the result will be 300 rows.
What you using is Multitable SELECT.
Multitable SELECT (M-SELECT) is similar to the join operation. You
select values from different tables, use WHERE clause to limit the
rows returned and send the resulting single table back to the
originator of the query.
The difference with M-SELECT is that it would return multiply tables
as the result set. For more deatils: https://dev.mysql.com/worklog/task/?id=358
In other word, you query is :
SELECT *
FROM a
CROSS JOIN b
WHERE b.id in (1,2,3)

How to do a join on 2 tables, but only return the data for one table?

I am not sure if this is possible. But is it possible to do a join on 2 tables, but return the data for only one of the tables. I want to join the two tables based on a condition, but I only want the data for one of the tables. Is this possible with SQL, if so how? After reading the docs, it seems that when you do a join you get the data for both tables. Thanks for any help!
You get data from both tables because join is based on "Cartesian Product" + "Selection". But after the join, you can do a "Projection" with desired columns.
SQL has an easy syntax for this:
Select t1.* --taking data just from one table
from one_table t1
inner join other_table t2
on t1.pk = t2.fk
You can chose the table through the alias: t1.* or t2.*. The symbol * means "all fields".
Also you can include where clause, order by or other join types like outer join or cross join.
A typical SQL query has multiple clauses.
The SELECT clause mentions the columns you want in your result set.
The FROM clause, which includes JOIN operations, mentions the tables from which you want to retrieve those columns.
The WHERE clause filters the result set.
The ORDER BY clause specifies the order in which the rows in your result set are presented.
There are a few other clauses like GROUP BY and LIMIT. You can read about those.
To do what you ask, select the columns you want, then mention the tables you want. Something like this.
SELECT t1.id, t1.name, t1.address
FROM t1
JOIN t2 ON t2.t1_id = t1.id
This gives you data from t1 from rows that match t2.
Pro tip: Avoid the use of SELECT *. Instead, mention the columns you want.
This would typically be done using exists (or in) if you prefer:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 on t2.x = t1.y);
Although you can use join, it runs the risk of multiplying the number of rows in the result set -- if there are duplicate matches in table2. There is no danger of such duplicates using exists (or in). I also find the logic to be more natural.
If you join on 2 tables.
You can use SELECT to select the data you want
If you want to get a table of data, you can do this,just select one table date
SELECT b.title
FROM blog b
JOIN type t ON b.type_id=t.id;
If you want to get the data from two tables, you can do this,select two table date.
SELECT b.title,t.type_name
FROM blog b
JOIN type t ON b.type_id=t.id;

Merge two tables to one and remove duplicates

I have 2 tables in the same database.
I want to merge them based on the common id column. Because the tables are too huge I am not sure if there are duplicates.
How is it possible to merge these two tables into one based on the id and be sure that there are no duplicates?
SELECT *
FROM table1,table2
JOIN
GROUP BY id
What do you mean by merging two tables? Do you want records and columns from both the tables or columns from one and records from both?
Either way you will need to change the join clause only.
You could do a join on the columns you wish to
SELECT DISTINCT *
FROM table1 tb1
JOIN table2 tb2
ON table1.id = table2.id
Now if you want columns from only table1 do a LEFT JOIN
If you want columns from only table2 then a RIGHT JOIN
If you want columns from both the tables, use the query as is.
DISTINCT ensures that you get only a single row if there are multiple rows with the same data (but this distinct will check values for all columns in a row whether they are different or the same)
Union won't help if both tables have different number of columns. If you don't know about joins then use a Cartesian product
select distinct *
from table1 tb1, table2 tb2
where tb1.id = tb2.id
Where id is the column that is common between the tables.
Here if you want columns from only table1 do
select distinct tb1.*
Similarly replace tb1 by tb2 in the above statement if you just want table2 columns.
select distinct tb2.*
If you want cols from both just write '*'
In either cases I.e. joins and products said above if you need selective columns just write a table alias. E.g.
Consider :
table1 has id, foo, bar as columns
table2 has id, name,roll no, age
you want only id, foo, name from both the tables in the select query result
do this:
select distinct tb1.id, tb1.foo, tb2.name
from table1 tb1
join table2 tb2
on tb1.id=tb2.id
Same goes for the Cartesian product query. tb1, tb2 are BTW called as a table aliases.
If you want data from both the tables even if they have nothing in common just do
select distinct *
from table1 , table2
Note that this cannot be achieved using a join as join requires a common column to join 'on'
I am not sure What exactly do you want but anyway, this is your code
SELECT *
FROM table1,table2
JOIN
GROUP BY id
i just edit your query
SELECT *
FROM table1 JOIN table2
on table2.id = table1.id
GROUP BY table1.id // here you have to add table
//on which you will be group by at this moment this is table1
Try UNION:
https://dev.mysql.com/doc/refman/5.0/en/union.html
IT is very simple. Hope it will help.
Also you should have a look at "DISTINCT".

Selecting from two tables, with different columns, where one needs a count

I have two tables, TableA and TableB.
I need to select one count value from TableA, based on a where condition.
I need to select two values from TableB.
I'd like all the values in one result set. There will never be more than one row in the result set.
Here's what I have now:
SELECT count(id) FROM TableA WHERE ($some_where_statement) SELECT owner, owner_ID from TableB
I know this should be simple, but this is throwing an error. Any suggestions?
You can cross join to join rows from two unrelated tables:
SELECT T1.cnt, T2.owner, T2.owner_ID
FROM (SELECT count(id) FROM TableA WHERE ($some_where_statement)) AS T1
CROSS JOIN (SELECT owner, owner_ID from TableB) AS T2
To have only one row in the result set, it is assumed that both subqueries only return one row. I suspect that this is not the case for the second subquery. You are probably missing a where clause.