I am trying to get different values on rows of one table, and I can't think of how to that.
Lets say for example:
table1
id | name | empCode | insCode
1 John | E101 | I101
table2
id | code | name | role
1 | E101 | Mich | 2
2 | I101 | Bran | 3
table1 has reference id of table2, and empCode and insCode in table1 dependes on code and role in table2.
What I want is like this:
id | code | name | empCode | insCode | role |
1 | ? | John | E101 | I101 | ? |
I honestly don't know if its possible to retrieve multiple rows in same table in one select query.
If its not, what other possible solutions can I go with?
There is problem in your table design but you can get as your expected with below query:
select
result1.id,
result1.code,
result1.name,
result1.empCode,
result1.insCode,
result1.role as role_of_empCode,
result2.role as role_of_insCode
from (
SELECT tbl1.id,
tbl2.code,
tbl1.name,
tbl1.empCode,
tbl1.insCode,
tbl2.role
FROM `table2` tbl2
INNER JOIN `table1` tbl1
on tbl2.code = tbl1.empCode
) as result1,
`table2` result2
where result1.insCode = result2.code
ORDER BY result1.id;
You can check in this link!
Try something like:
SELECT a.*, b.role FROM
table1 a inner join table2 b on a.id=b.id
Also you may want to consider removing empcode and inscode from table 2 since its being redundant in table 1 OR vice versa depending on what your objectives are.
Related
New to SQL
Suppose we have two tables
One has got the ID and Name column :
+----+-------+
| ID | Name |
+----+-------+
| 1 | Sam |
| 1 | Dan |
+----+-------+
and the second one has also got two columns as follow :
+----+------------+
| ID | Relatives |
+----+------------+
| 1 | Uncle |
| 2 | Aunty |
+----+------------+
If we do inner join we would only get the rows where the condition satisfies. But i want the output to be Like
+------+------------+
| ID | Relatives |
+------+------------+
| 1 | Uncle |
| NULL | Aunty |
+------+------------+
once only the value in the ID column should be shown. If the occurrence is twice or thrice it should come as null.
Just tell me if it is possible or not? and How for both the cases.
As your question is not clear, so assuming that you need to retrieve id from table a and name from table b and you also want to avoid duplicate rows, then an option could be to use distinct along with left join:
select distinct a.id, b.name
from b
left outer join a
on b.id = a.id
order by id desc
Result:
+------+-------+
| id | name |
+------+-------+
| 1 | Uncle |
| NULL | Aunty |
+------+-------+
DEMO
Try this:
SELECT
T1.Id,
T2.Relatives
FROM SecondTable T2
LEFT JOIN FirstTable T1
ON T1.ID = T2.ID
GROUP BY T1.Id,
T2.Relatives
This is what I get exactly:
CREATE TABLE #a (
id int,
name varchar(10)
)
CREATE TABLE #b (
id int,
name varchar(10)
)
INSERT INTO #a
VALUES (1, 'sam')
INSERT INTO #a
VALUES (1, 'Dan')
INSERT INTO #b
VALUES (1, 'Uncle')
INSERT INTO #b
VALUES (2, 'Aunty')
SELECT
T1.Id,
T2.name
FROM #b T2
LEFT JOIN #a T1
ON T1.ID = T2.ID
GROUP BY T1.Id,
T2.name
DROP TABLE #a
DROP TABLE #b
Output:
Id name
NULL Aunty
1 Uncle
Hope, this is what you ask in your question.
How to put a column in the IN?
Example:
SELECT tb1.*,
(SELECT GROUP_CONCAT(name)
FROM tb2
WHERE id IN( tb1.ids_tb2 )) AS names
FROM tb1
Column tb1.ids_tb2 stores "1,2,3"
This is not working.
++++
I need 'ids_tb2' inside the IN
Example Tables http://sqlfiddle.com/#!9/08cfa9/1
Ids_tb2 = 1,3,4
Names != Fruit1,Fruit3,Fruit4
tks
Your table structure is not really ideal for this task. In database design you should always preserve the 'atomicity' of data, i. e. you should never work with lists of ids in any column. Instead use a link table lnk like this
| gid | fid |
|-----|-----|
| 1 | 1 |
| 1 | 3 |
| 1 | 4 |
| 2 | 1 |
| 2 | 5 |
Having such a structure you can then very easily do
SELECT grp , GROUP_CONCAT(name) fruits
FROM tb1
INNER JOIN lnk ON gid=grid
INNER JOIN tb2 ON frid=fid
GROUP BY grp
see here (demo).
The result will be
| grp | fruits |
|------|----------------------|
| Blue | Fruit1,Fruit3,Fruit4 |
| Red | Fruit1,Fruit5 |
Having said that - you could also do the following with your original database design (see here):
SELECT tb1.id,`group`,GROUP_CONCAT(name) fruits
FROM tb1
INNER JOIN tb2 ON FIND_IN_SET(tb2.id,ids_tb2)>0
GROUP BY `group`
Although I would not recommend doing this. Also you should not be using reserved SQL names for your columns like group, as you will always have to use back-ticks to mask them.
Revisiting ...
Actually, your initial approach does also work, you just have to replace your IN (..) clause by a FIND_IN_SET(..) function call like
SELECT tb1.*,
(SELECT GROUP_CONCAT(name) FROM tb2
WHERE FIND_IN_SET(tb2.id, tb1.ids_tb2)>0) names
FROM tb1
You can do a simple select in the in. Just like this:
SELECT tb1.*,
(SELECT GROUP_CONCAT(name)
FROM tb2
WHERE id IN(select * from tb1.ids_tb2 )) AS names
FROM tb1
There are two tables with details as mentioned below in MySQL:
TABLE 1:
+-------------+---------------+
| user_id | isactive |
+-------------+---------------+
| aaa | 0 |
+-------------+---------------+
| bbb | 0 |
+-------------+---------------+
TABLE 2:
+-------------+---------------+-----------+
|store_no | owner | store |
+-------------+---------------+-----------+
|1234 | aaa | aaa,xyz |
+-------------+---------------+-----------+
|1006 | aaa | aaa |
+-------------+---------------+-----------+
|1005 | ccc | www |
+-------------+---------------+-----------+
I need to fetch rows from table 1 whose entries are neither in 'owner' nor in 'store' column of table 2. For example, in the above scenario, the resultset should contain 'bbb'.
I tried using find_in_set, locate etc but could not fetch the details as required. Please help..
Updated Tables format
Query:
select a.user_id from table1 u
left outer join table2 a
on (owner=user_id or concat(',',store,',') like concat('%,',user_id,',%'))
where (find_in_set(user_id,owner) = 0 or find_in_set(user_id,store) = 0)
and isactive=0
FYI, store column can have concatenated values of more than one userid
You can try using NOT EXISTS
SELECT
T1.user_id
FROM TABLE_1 T1
WHERE NOT EXISTS (
SELECT 1
FROM
TABLE_2 T2
WHERE T2.owner = T1.user_id OR FIND_IN_SET(T1.user_id,T2.store) > 0
);
SQL FIDDLE DEMO
Suggestion:
Is storing a delimited list in a database column really that bad?
You can do it like following :-
SELECT * FROM table1 WHERE user_id NOT IN (SELECT owner FROM table2) AND NOT FIND_IN_SET(user_id, (SELECT store FROM table2));
Second option :-
SELECT * FROM table1 WHERE user_id NOT IN (SELECT owner FROM table2) AND FIND_IN_SET(user_id, (SELECT store FROM table2)) = 0;
It may help you.
I think this should work:
select user_id
from table1
where user_id not in
(select owner from table2)
and not find_in_set(user_id,
(select store from table2)
);
I'm trying to export multiple MySQL tables into a single CSV file, these tables have different number of columns and have nothing in common. An example is below:
table1:
ID| Name
1 | Ted
2 | Marry
null| null
table2:
Married| Age | Phone
Y | 35 | No
N | 25 | Yes
Y | 45 | No
The result that I want to get is:
ID| Name | Married | Age | Phone
1 | Ted | Y | 35 | No
2 | Marry | N | 25 | Yes
null| null | Y | 45 | No
Is it possible to do using MySQL commands? I have tried all types of join but it doesn't give me the result that I need.
Try this query:
SELECT * FROM
(SELECT #n1:=#n1+1 as 'index', Table1.* FROM Table1, (select #n1:=0)t)t1
natural join (SELECT #n2:=#n2+1 as 'index', Table2.* FROM Table2, (select #n2:=0)t1)t2 ;
You can see in this fiddle a working example.
In the example we generate an index column for Table1 and Table2 and natural join the 2 tables.
This way the join is done using the row position as returned by the SELECT of tables without any ORDER operator and usually this is not a good idea!
I'm not quite sure you understand what you are asking but sure you can join two tables without really caring on which rows will be matched:
SET #i1=0;
SET #i2=0;
SELECT * INTO OUTFILE 'xyz' FIELDS TERMINATED BY ','
FROM (SELECT #i1:=#i1+1 as i1, table1.* FROM table1) AS a
JOIN (SELECT #i2:=#i2+1 as i2, table2.* FROM table2) b ON (a.i1=b.i2);
I have a table
--------------------
ID | Name | RollNO
--------------------
1 | A | 18
--------------------
2 | B | 19RMK2
--------------------
3 | C | 20
--------------------
My second table is
-----------------------
OldRollNo | NewRollNo
-----------------------
18 | 18RMK1
-----------------------
19 | 19RMK2
-----------------------
20 | 20RMK3
-----------------------
21 | 21RMK4
-----------------------
22 | 22RMK5
-----------------------
I want the resulting table like
----------------------------------
ID | Name | RollNo | LatestRollNo
----------------------------------
1 | A | 18 | 18RMK1
----------------------------------
2 | B | 19RMK2 | 19RMK2
----------------------------------
3 | C | 20 | 20RMK3
----------------------------------
What would be the select query like? This is just the replica of my problem. I have used CASE Statement with the select query but as the records in my table is large, it's taking too much time. In my second table the OldRollNo Column is unique.One more thing is that in the resultant RollNo column if the newly assigned RollNo is already present then it should be copied exactly to the next column i.e LatestRollNo. I have to check only those RollNo which are old.
Thanks.
Try something like this:
select t1.ID
, t1.Name
, t1.RollNO
, LatestRollNO = coalesce(n.NewRollNo, o.NewRollNo)
from t1
left join t2 o on t1.RollNO = o.OldRollNo
left join t2 n on t1.RollNO = n.NewRollNo
SQL Fiddle with demo.
It sounds like your issue is performance not logic; something like this should hopefully allow approriate index usage assuming you have the appropriate indexes on t2.OldRollNo and t2.NewRollNo.
The problem with OR or CASE in a WHERE clause is that these don't always lend themselves to efficient queries; hopefully this will be a bit more useful in your case.
select f.ID, f.name, f.RollNo, s.NewRollNo as "Latest RollNo"
from FirstTable f
inner join
SecondTable s on f.RollNo = s.OldRollNo or f.RollNo = s.NewRollNo
select t.id,t.name,t.rollno,tt.newrollno as latestrollno from
talble1 t
left join
table2 tt on t.rollno = tt.oldrollno
You need to use inner join.
SELECT t1.ID,t1.Name,t2.RollNo,t2.NewRollNo AS LatestRollNo
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.RollNo=t2.OldRollNo OR t1.RollNo=t2.NewRollNo