Table 1
ID | NAME | WARD_ID|
1 A 1
2 B 1
3 C 2
4 D 2
Table 2
ID | MONTH1 | MONTH2 | WARD_ID|
1 9 10 1
2 6 11 1
3 5 12 2
4 13 14 2
I want to join this two table and produce the following output:
ID | NAME | MONTH1 | MONTH2 | WARD_ID|
1 A 9 10 1
2 B 6 11 1
3 C 5 12 2
4 D 13 14 2
In the ON condition of the query I have to keep WARD_ID equal for both the tables. I could not able to figure out the solution. Anyone have any experience with a query like this?
I think you want something like this:
select t1.*, t2.*
from (select t1.*,
(#rn1 := if(#w1 = ward_id, #rn1 + 1,
if#w1 := ward_id, 1, 1)
)
) as rn
from (select t1.* from table1 t1 order by ward_id, id ) t1 cross join
(select #w1 := -1, #rn1 := -1) params
) t1 join
(select t2.*,
(#rn2 := if(#w2 = ward_id, #rn2 + 1,
if#w2 := ward_id, 1, 1)
)
) as rn
from (select t2.* from table2 t2 order by ward_id, id ) t2 cross join
(select #w2 := -1, #rn1 := -1) params
) t1
on t2.ward_id = t1.ward_id and t2.rn = t1.rn;
The subqueries enumerate the rows in each table. The join then uses the enumeration.
This is much simpler in MySQL 8.0, using row_number().
I'm assuming here that ID is intended to be the same from both tables. If so, I think you can do a multi-condition join:
select * from table1 t1
inner join table2 t2
on t1.ID=t2.ID and t1.WARD_ID=t2.WARD_ID
You can do something like:
SET #rn:=0;
SET #rn2:=0;
SELECT *
FROM (
SELECT #rn:=#rn+1 AS rn1, t1.ID, t1.NAME, t1.WARD_ID
FROM t1
GROUP BY t1.WARD_ID, t1.NAME
ORDER BY t1.WARD_ID, t1.NAME
) s1
INNER JOIN (
SELECT #rn2:=#rn2+1 AS rn2, t2.ID, t2.MONTH1, t2.MONTH2, t2.WARD_ID
FROM t2
GROUP BY t2.WARD_ID, t2.MONTH1,t2.MONTH2
ORDER BY t2.WARD_ID, t2.MONTH1,t2.MONTH2
) s2 ON s1.WARD_ID = s2.WARD_ID
AND s1.rn1 = s2.rn2
But it really doesn't reliably sort the tables to join the same rows every time. I still think there isn't a reliable/repeatable way to join the two tables the same every time.
============================================================
http://sqlfiddle.com/#!9/aa2db0/1 <<<< If ID can be used to reliably sort the two tables, you can use it in the ORDER BYs. I've added it in this Fiddle, and included rows in the setup that would fall before the existing records and potentially change the sorting. This also includes more records in Table 2 than there are in Table 1, so would possibly result in duplicated rows. These new rows are ignored since they can't be matched between tables.
Related
I want to get random combinations of id of a table with itself.
SELECT id FROM t1
SELECT id as id2 FROM t1 ORDER BY RAND()
SELECT id as id3 FROM t1 ORDER BY RAND()
How can I JOIN these queries to get
SELECT id,id2,id3
1 random_id random_id
2 random_id random_id
3 random_id random_id
4 random_id random_id
5 random_id random_id
In other words, what can be the point of JOINing to simply place these three SELECTs side by side.
It is beneficial to create a unique combination, but with the above query ORDER BY RAND() can repeat the same id to id2 and id3. The former case is ideal, but the latter sufficiently works for me.
If you are using MySQL 8+, then ROW_NUMBER might work here:
WITH cte AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY id) rn1,
ROW_NUMBER() OVER (ORDER BY RAND(UNIX_TIMESTAMP())) rn2,
ROW_NUMBER() OVER (ORDER BY RAND(UNIX_TIMESTAMP()+1)) rn3
FROM t1
)
SELECT
t1.id,
t2.id AS id2,
t3.id AS id3
FROM cte t1
INNER JOIN cte t2
ON t1.rn1 = t2.rn2
INNER JOIN cte t3
ON t1.rn1 = t3.rn3;
The demo below was from a sample table containing the id values from 1 to 10 inclusive.
Demo
If you truly want random, then repeats are allowed. That suggests:
select t.*,
(select t2.id
from t t2
order by rand()
limit 1
) as id2,
(select t3.id
from t t3
order by rand()
limit 1
) as id3
from t;
If you want permutations in older versions of MySQL, then variables are handy:
select t.id, t1.id, t2.id
from (select t.id, (#rn := #rn + 1) as seqnum
from t cross join
(select #rn := 0) params
) t join
(select t.id, (#rn1 := #rn1 + 1) as seqnum
from (select t.* from t order by rand()) t cross join
(select #rn1 := 0) params
) t1
using (seqnum) join
(select t.id, (#rn2 := #rn2 + 1) as seqnum
from (select t.* from t order by rand()) t cross join
(select #rn2 := 0) params
) t2
using (seqnum);
In MySQL 8+, Tim's answer is the best approach.
Here is a db<>fiddle
For this sample data of sequential ids from 1 to n, this query that uses string functions will work and will return in the columns id2 and id3 all if the ids once:
select t1.id,
find_in_set(t1.id, t2.ids2) id2,
find_in_set(t1.id, t3.ids3) id3
from tablename t1
cross join (
select group_concat(id order by rand()) ids2
from tablename
) t2
cross join (
select group_concat(id order by rand()) ids3
from tablename
) t3
See the demo.
Results (like):
| id | id2 | id3 |
| --- | --- | --- |
| 1 | 5 | 4 |
| 2 | 2 | 5 |
| 3 | 1 | 2 |
| 4 | 4 | 3 |
| 5 | 3 | 1 |
I want to select from two table column datas and insert it into another table I can this but it copy 6 times.
I tried this code it works but insert 6 time in to table3.
insert into table3(LisanNo , UserName, table1ID,
NameAndLastName , table2Id)
select table1.LisansNo, table1.UserName, table1.Id,
table2.NameAndLastName,table2.Id
form table1, tabl2;
Enter code here-
**Table1**
id LisansNo UserName
1. f3ewrwer aaa
2. r3we3 bbb
**Table2**
id NameLastName
3. john ddd
4. hhhhh
9. yyyy
11. terere
I want to insert this Two table to another table.
table 3
id LisanNo UserName table1ID NameLastName Table2ID
1. f3ewrwer aaa 1 john ddd 3
2. r3we3 bbb 2 hhhhh 4
3. yyyy 9
4. terere 11
You seem to want to list the values vertically. This is not a very SQL'ish thing to do, but you can accomplish it:
select t1.LisansNo, t1.UserName, t1.Id,
t2.NameAndLastName, t2.Id
from (select t1.*, (#rn1 := #rn1 + 1) as seqnum
from table1 cross join
(select #rn1 := 0) params
) t1 left join
(select t2.*, (#rn2 := #rn2 + 1) as seqnum
from tabl2 t2 cross join
(select #rn2 := 0) params
) t2
on t1.seqnum = t2.seqnum;
I have a table 1 with a one to many relationship to table 2.
Table 1 also has a one to many relationship with table 3
I want to combine the results of the join but all im getting is repeated values
Here is the structure:
table 1
reportnumber
1
2
3
table 2
reportnumber col1
1 a
1 b
2 c
3 a
table 3
reportnumber col2
1 x
1 y
1 z
2 w
expected result set
reportnumber col1 col2
1 a x
1 b y
1 z
2 c w
3 a
I'm sure this is possible with a left outer join but i just cant get the syntax right
Any clues?
This is what im trying
select * from table1 a
left outer join table2 b on a.reportnumber=b.reportnumber
left outer join table3 on a.reportnumer=c.reportnumber
But the results look like this
reportnumber col1 col2
1 a x
1 a y
1 a z
1 b x
1 b y
1 b z
...
This isn't easy in MySQL, but you can do it with variables. This has little to do with a join. Or, it has a lot to do with join, but you don't have the right join keys and you don't have full outer join.
The solution is to enumerate the rows from each table with the data columns. Then aggregate using the enumeration and reportnumber:
select reportnumber, max(col1) as col1, max(col2) as col2
from ((select t2.reportnumber, col1, null as col2, #rn2 := #rn2 + 1 as rn
from table2 t2 cross join
(select #rn2 := 0) const
) union all
(select t3.reportnumber, null, t3.col2, #rn3 := #rn3 + 1 as rn
from table3 t3 cross join
(select #rn3 := 0) const
)
) t
group by reportnumber, rn;
I have 2 tables as follows
t1:
id code field1 field2
1 1000 a1111 a2222
2 2000 b1111 b2222
3 1000 a3333 a4444
4 2000 b3333 b4444
5 2000 b5555 b6666
6 3000 c1111 c2222
7 3000 c3333 c4444
8 3000 c5555 c6666
t2:
t2id t1_code var1
1 1000 xxxx
2 2000 yyyyy
3 3000 zzz
4 3000 mmm
i want the result table as:
code field1 field2 t1_code var1
1000 a3333 a4444 1000 xxxx
1000 a1111 a2222 null null
2000 b3333 b4444 2000 yyyyy
2000 b5555 b6666 null null
2000 b1111 b2222 null null
3000 c1111 c2222 3000 mmm
3000 c3333 c4444 3000 zzz
3000 c3333 c4444 null null
i tried :
SELECT t1.code, t1.field1, t1.field2, t2.t1_code, t2.var1
FROM t2, t1
WHERE t1_code = code
ORDER BY code
is not giving me the answer.
Please help...
Okay, you want the join to go to the "first" matching row in t1 (where "first" means lowest id).
Here is almost a way to do it:
SELECT t1.code, t1.field1, t1.field2, t2.t1_code, t2.var1
FROM t1 left outer join
(select t1.code, min(id) as minid
from t1
group by t1.code
) t1min
on t1.id = t1min.minid left outer join
t2
on t2.t1_code = t1min.code;
What this does is join the original table to another table to find the minimum id for each code. By joining on the ids, the t1min.code will only have values at the min ids. The final join just brings in the code for these.
EDIT:
The actual problem is a bit more complicated. I think the best way is simply to enumerate the values in each table and do the join with two keys:
select t1.code, t1.field1, t1.field2, t2.t1_code, t2.var1
from (select t1.*,
#rn1 := if(#code = code, #rn1 + 1, 1) as rn, #code := code
from t1 cross join
(select #rn1 := 0, #code := '') const
order by code, id
) t1 left outer join
(select t2.*,
#rn2 := if(#code = t1_code, #rn2 + 1, 1) as rn, #code := t1_code
from t2 cross join
(select #rn2 := 0, #code := '') const
order by t1_code, t2id
) t2
on t1.code = t2.t1_code and t1.rn = t2.rn
order by t1.id;
Example:
First Query:
select A,B,C from tb1;
---------------
A B C
---------------
1 1 3
2 1 4
Second Query:
select E from tb2;
---------------
E
---------------
8
9
The required result format should be like this:-
-----------------------
A B C E
-----------------------
1 1 3 8
2 1 4 9
Please tell me the query how to get the result set.
to make your tables better structured if you can add in both tables a column id to identify the row number of each table.
then you can easily merge two table which have same id . the relation here is the id column.
then you could do this
select A, B, C , E from Table1 t1
inner join Table2 t2
on t1.id = t2.id
please see structured tables in this DEMO HERE
THE RESULT:
A B C E
1 1 3 8
2 1 4 9
hope it helps you !
SQL tables are inherently unordered. This poses a problem, because there is nothing in your table to specify the ordering of the rows, which seems to be the connection between the two tables.
So, you have to hold your breath and make some assumptions. The particular assumption is that the data returned by a select is the actual order you want in the table (it could be different if you have deletes in the table or are running in a parallel environment).
The following code adds an id to each table. This id can then be used for the join:
select t1.A, t1.B, t1.C, t2.D
from (select t1.*, #rn := #rn + 1 as id
from tbl1 t1 cross join (select #rn := 0)
) t1 left outer join
(select t2.*, #rn := #rn + 1 as id
from tbl2 t2 cross join (select #rn := 0)
) t2
on t1.id = t2.id
Hi may be it's help for you
you can try like this
SELECT * FROM tb1,tb2
And you get output like
-----------------------
A B C E
-----------------------
1 1 3 8
2 1 4 9