Select Distinct between two tables inner join - mysql

I have table 1 which contains unique values and table 2 which contains multiple values for the same email. What I want to do is select the first value of 'id' - table 2 contains a number of ids and matching emails
SELECT DISTINCT
table1.email,
table2.id FROM
table1
INNER JOIN users ON table1.email = table2.Email
the problem is the output needs to be unique - i.e. one ID - the first one from table2 that is associated with a given email - currently we're getting multiple results - no unique or distinct values.

Probably
any id - add ORDER BY RAND()
1 row of result - add LIMIT 1.
So, the query might be something like this:
SELECT DISTINCT
table1.email,
table2.id
FROM table1
INNER JOIN table2 ON table1.email = table2.email
ORDER BY RAND()
LIMIT 1
Based on new information, it seems like you're looking for something like this instead:
Note: Works on MySQL v8+ and MariaDB 10.2+ that have window function:
SELECT email, id
FROM
(SELECT table1.email,
table2.id,
ROW_NUMBER()
OVER
(PARTITION BY table1.email ORDER BY table2.id) AS 'RowNumber'
FROM table1
INNER JOIN table2 ON table1.email = table2.email) t
WHERE RowNumber=1;
Assign ROW_NUMBER() with table1.email as partition and sort by table2.id ascending (note that the default sorting of ORDER BY is ascending so there's no need to define it as ORDER BY xxx ASC).
Turn the base query into a subquery then do a SELECT .. with condition of WHERE RowNumber=1. Hence, it will return only a single row for each email.
Alternatively, depending on your data, you could just simply do something like this:
SELECT table1.email,
MIN(table2.id) AS minID
FROM table1
INNER JOIN table2 ON table1.email = table2.email
GROUP BY table1.email;
Demo fiddle

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

Why does group by and sort by give 0 response

The result of this query gives me 0 rows where it should give me the 3 latest rows (grouped by Table1.Name).
Table1 has: "Name", "Timestamp", "Voltage".
Table2 has: "Name", "data".
When I delete "ORDER BY Table1.Timestamp" I do get 3 rows (as expected) but they are the 3 oldest entries in the database where I want the 3 latest.
(I have 3 Name values in Table1 and Table2 that match).
The code:
SELECT * from Table1
INNER JOIN Table2
ON Table1.Name=Table2.Name
GROUP BY Table1.Name
ORDER BY Table1.Timestamp;
You can try to perform a query like this :
SELECT t.*,t2.* from Table1 t
INNER JOIN Table2 t2
ON t.Name=t2.Name
WHERE t.Timestamp = (
SELECT MAX(t3.Timestamp) FROM Table1 t3
WHERE t3.Name = t.Name
)
You could sort and taking the top 3:
SELECT * from Table1
INNER JOIN Table2
ON Table1.Name=Table2.Name
ORDER BY Table1.Timestamp DESC
LIMIT 3
When you are using join two or more tables then don't use * in select query. Use specific column name to avoid column ambiguously in select query , you can also use Table1., Table2. but good way to use specific columns in select query.
SELECT Table1.Name,Table1.Timestamp from Table1
INNER JOIN Table2
ON Table1.Name=Table2.Name
GROUP BY Table1.Name
ORDER BY Table1.Timestamp;

How to apply result of order by clause from subquery to main query

I have 2 tables which are linked by column named MID.
I want to fetch name from 1st table but the sequence is mentioned in 2nd table.
My query is as follows:
select name from table1 where MID in(select MID from table2 where CID="100" ORDER BY sequenceNum);
If i only run the query mentioned inside brackets then i get the data ordered by sequence.
But the above query is fetching the data from db as it is and not arranging it in sequence. What can be the problem?
I think this shoukld do the trick...
SELECT name FROM table1
INNER JOIN table2 ON Table2.MID = table1.MID AND CID="100"
ORDER BY
table2.sequenceNum
You want merge two tables and order results by merged table:
SELECT table1.name
FROM table1
LEFT JOIN table2 ON (table2.MID = table1.MID)
WHERE table2.CID = "100"
ORDER BY table2.sequenceNum;
or
SELECT table1.name
FROM table1
LEFT JOIN table2 ON (table2.MID = table1.MID AND table2.CID = "100")
ORDER BY table2.sequenceNum;
If you want get field from concrete table, use table prefix like table1.name

SQL Count + Left join + Group by ... Missing rows

Trying to list all what's in table 1 and records under it in table 2
Table one each row has an id , and each row in table 2 has idontable1
select table1.*, count(table2.idintable1)as total
from table1
left join table2 on table1.id=table2.idintable1
WHERE table1.deleted='0' AND table2.deleted=0
group by
table2.idintable1
My current problem is rows from table1 with 0 records in table2 are not displayed
I want them to be displayed
The query that you want is:
select t1.*, count(t2.idintable1) as total
from table1 t1 left join
table2 t2
on t1.id = t1.idintable1 and t2.deleted = 0
where t1.deleted = 0
group by t1.id;
Here are the changes:
The condition on t2.deleted was moved to the on clause. Otherwise, this turns the outer join into an inner join.
The condition on t1.deleted remains in the where clause, because presumably you really do want this as a filter condition.
The group by clause is based on t1.id, because t2.idintable1 will be NULL when there are no matches. Just using t1.id is fine, assuming that id is unique (or a primary key) in table1.
The table aliases are not strictly necessary, but they make queries easier to write and to read.
You should GROUP BY table1.id.
The LEFT JOIN ensures all the rows from table1 appear in the result set. Those that do not have a pair in table2 will appear with NULL in field table2.idintable1. Because of that your original GROUP BY clause produces a single row for all the rows from table1 that do not appear in table2 (instead of one row for each row of table1).
You have fallen into mysql's non-standard group by support trap.
Change your group by to list all columns of table 1:
group by table1.id, table1.name, etc
or list the column positions of all table1 columns in the select:
group by 1, 2, 3, 4, etc
Or use a subquery to get the count vs the id, and join table1 to that.

sql left join with distinct correct?

I'm trying to do a join between tables 1 and 2 which have a 1 to many relationship.
table1 has the following fields
createdate
contact
tkey (surrogate key)
table2 has the following fields
tkey (primary key)
status
userfld1
description
I want to show all items in table2 with their corresponding items in table1 grouped by table2.userfld1
select distinct t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
from table2 as t2 left join table1 as t1
on t2.tkey = t1.tkey
group by t2.userfld1
is this correct?
No that's not correct, you can't select columns that aren't in the group by unless they are contained in an aggregate function. And I think what you are asking for doesn't even make sense. My best guess is that you mean ORDER BY, not GROUP BY:
SELECT DISTINCT t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
FROM table2 t2
LEFT JOIN table1 t1
ON t2.tkey = t1.tkey
ORDER BY t2.userfld1
Three other errors that I've fixed:
SELECT ... FROM not SELECT ... WHERE
You should join with a table, not a column.
You had no aliases after the table names, but later refer to these missing aliases.
I think what you're looking for is order by, not group by, and I also fixed your query:
select t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
where table2 t2 left join table1 t1
on t2.tkey = t1.tkey
order by t2.userfld1
Is this what you were looking for?