mysql select from one table if its name is in another table - mysql

So what I have is something like this:
main_table
id | in_table | in_tables_id | points
1 | t1 | 1 | 1
2 | t2 | 1 | 4
3 | t2 | 2 | 3
4 | t1 | 2 | 2
and then tables
table1 - which in my main_table is marked as t1
id | content_id
1 | 1
2 | 2
table2 - which in my main_table is marked as t2
id | content_id
1 | 1
2 | 2
content
id | category_id | content
1 | 1 | aaa
2 | 2 | bbb
categories
id | name
1 | first
2 | seccond
3 | third
So my first table "main_table" has ids of entries from "table1" and "table2" for which users got their points, those entries are connected to "content" by content_id = id from "content" table; and that content in "content" table is allways in some category from "categories" table.
What I want is to sum all points from "main_table" by categories from "categories" table.
The main problem for me is to somehow "connect" identifiers from "main_table" like t1, t2 with tables "table1", "table2", is there a way to do it?

I recommend restructuring your DB. Have a look at normal forms and transform your tables into normal form, e.g. don't use separate tables, but store the "table name" in a column, so you can do easy joins.
For your current table layout use something like the following join conditions:
select *
from main_table mt
inner join table1 t1
on mt.in_table = 't1'
and mt.in_tables_id = t1.id
inner join table2 t2
on mt.in_table = 't2'
and mt.in_tables_id = t2.id
/* repeat for number of tables */

Related

MySQL - dont show any row from ID use

I just need to show the values that don't use the specifically ID.
I have two table
table 1
id_xx
1
2
3
4
5
table 2
id | id_xx
3 | 3
4 | 3
4 | 1
I need this results for example. I say which results from ID i need
i need this result where id=3
id_xx
1
2
4
5
or where id=4
id_xx
2
4
5
or where id=1
1
2
3
4
5
You can LEFT JOIN table1 with table2 and apply the filter in the ON clause of the JOIN, and then filter on unmatched records:
SELECT t1.id_xx
FROM table1 t1
LEFT JOIN table2 t2 ON t2.id_xx = t1.id_xx AND t2.id = ?
WHERE t2.id IS NULL
You can replace the question mark with the id that you need to check.
Demo on DB Fiddle:
Given t2.id = 3:
| id_xx |
| ----- |
| 1 |
| 2 |
| 4 |
| 5 |
Given t2.id = 4:
| id_xx |
| ----- |
| 2 |
| 4 |
| 5 |
Another approach is using a Correlated Subquery with NOT EXISTS():
SELECT t1.id_xx
FROM table1 AS t1
WHERE NOT EXISTS (SELECT 1
FROM table2 AS t2
WHERE t2.id = ? -- your input id here
AND t2.id_xx = t1.id_xx)
If you have large table(s), and are worried about performance of these queries, then you may define the following index:
For the correlated subquery, define composite index (id, id_xx) on table2.
ALTER TABLE table2 ADD INDEX(id, id_xx);
Assuming that id_xx is already a Primary Key in the table1. So, you don't need to define any index there. If not, then you can define an index on it.

INNER JOIN on One Table but different Parameter

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.

SQL return row from first table, and then joined tables separately

I have two tables. I want to select all rows from table 1, and any rows from table 2 that share the same id. I need to return the row from table 1, and then, if they exist, separately return the joined rows of both table 1 and 2. My current code below returns the row from table 1 if there is no match in table 2. However, if a match exists in table 2 it will only return the joined rows.
SELECT
table1.id,
COALESCE(table2.name, table1.name) AS name
FROM
table1
LEFT JOIN
table2
ON
table1.id = table2.id
WHERE
table1.stock = 0
And here's what I'm after:
**Table 1**
id | name | stock
101 | sock | 4
102 | hat | 0
103 | belt | 0
**Table 2**
id | name
101 | banana
102 | pear
102 | apple
**Query output**
id | name
102 | hat
102 | pear
102 | apple
103 | belt
From your output, I gather that you want something like all rows from both tables where the id in table one has a stock of 0.
select id, name
from table1
where stock = 0
union all
select id, name
from table2 t2
where exists (select 1 from table1 t1 where t1.id = t2.id and t1.stock = 0);

joining two tables, select values from two with second table having no records

I have two tables where i fetch values from both tables, the situation is the first table always contains records but second table may or maynot.
here are tables
TAB1
id | rank
1 | TL
2 | PL
3 | MG
TAB2
num | id | swiped_on
1 | 1 | 20-4-14
2 | 1 | 21-4-14
3 | 3 | 25-4-14
the result i want is,(only one record from the second table)
id | rank | swiped_on
1 | TL | 21-4-14
2 | PL | -------
3 | MG | 25-4-14
please help
You can use a left join with a subselect from table tab2
select t.*,t1.swiped_on
from TAB1 t
left join (select id , max(swiped_on) swiped_on
from TAB2 group by id
) t1
on(t.id = t1.id)
Fiddle demo
Or just get the max of swiped_on from tab2
select t.*,max(t1.swiped_on) swiped_on
from TAB1 t
left join TAB2 t1
on(t.id = t1.id)
group by t.id
Fiddle demo

SELECTING SUM based on conditional if from another table

Database: mysql > ver 5.0
table 1: type_id (int), type
table 2: name_id, name, is_same_as = table2.name_id or NULL
table 3: id, table2.name_id, table1.type_id, value (float)
I want to sum values, and count values in table 3 where table2.name_id are same and also include the values of id where is_same_is=name_id. I want to select all data in table3 for all values in table2.
Apologize if my question is not very clear, and if it has already been answered but I am unable to find a relevant answer. Or dont exactly know what to look for.
[data]. table1
id | type
=========
1 | test1
2 | test2
[data].table2
name_id | name | is_same_as
==============================
1 | tb_1 | NULL
2 | tb_2 | 1
3 | tb_3 | NULL
4 | tb_4 | 1
[data].table3
id | name_id | type_id | value
======================================
1 | 1 | 1 | 1.5
2 | 2 | 1 | 0.5
3 | 2 | 2 | 1.0
output:
name_id| type_id|SUM(value)
=======================================================
1 | 1 |2.0 < because in table2, is_same_as = 1
2 | 2 |1.0
I think the following does what you want:
select coalesce(t2.is_same_as, t2.name_id) as name_id, t3.type_id, sum(value)
from table_3 t3 join
table_2 t2
on t3.name_id = t2.name_id
group by coalesce(t2.is_same_as, t2.name_id), t3.type_id
order by 1, 2
It joins the table on name_id. However, it then uses the is_same_as column, if present, or the name_id if not, for summarizing the data.
This might be what you are looking for: (I haven't tested it in MySQL, so there may be a typo)
with combined_names_tab (name_id, name_id_ref) as
(
select name_id, name_id from table2
union select t2a.name_id, t2b.name_id
from table2 t2a
join table2 t2b
on (t2a.name_id = t2b.is_same_as)
)
select cnt.name_id, t3.type_id, sum(t3.value) sum_val
from combined_names_tab cnt
join table3 t3
on ( cnt.name_id_ref = t3.name_id )
group by cnt.name_id, t3.type_id
having sum(t3.value) / count(t3.value) >= 3
Here's what the query does:
First, it creates 'combined_names_tab' which is a join of all the table2 rows that you want to GROUP BY using the "is_same_as" column to make that determination. I make sure to include the "parent" row by doing a UNION.
Second, once you have those rows above, it's a simply join to table3 with a GROUP BY and a SUM.
Note: table1 was unnecessary (I believe).
Let me know if this works!
john...