MySQL: part of table-A join part of table-B - mysql

Here is problem I have:
Table A
id_a | name
---------------------
1 | name-A
2 | name-B
3 | name-C
4 | name-D
5 | name-E
6 | spcial_type
Table B
id_b | id_a | condition | subtype
-------------------------------------------------
1 | 2 | 1 | 1
2 | 1 | 0 | 1
3 | 1 | 1 | 2
4 | 2 | 0 | 1
5 | 4 | 0 | 1
6 | 5 | 1 | 1
7 | 2 | 1 | 3
Terms:
Table A: “special_type” exluded
Table A: rows not present in Table B included
Table B: all with condition=0 exluded
Result Table:
id_r | id_a | id_b | name | condition
-----------------------------------------------
1 | 1 | 3 | name-A | 1
2 | 2 | 1 | name-B | 1
3 | 5 | 6 | name-E | 1
4 | 2 | 7 | name-B | 1
5 | 3 | null | name-C | null
table A.subtype is only aux. to show that id_a can be stored many times with condition=1
What I tried:
select x.id_a, x.name, z.id_b, z.id_a, z.condition from Table A
LEFT JOIN Table z ON x. id_a = z. id_a
but this got me items with condition=0, which I do not want
so I tried:
select x.id_a, x.name, z.id_b, z.id_a, z.condition from Table A
LEFT JOIN Table z ON x. id_a = z. id_a where z.condition=1
but that idea excluded items from Table A not present in Table B, and I want these items.
Can it be don inside of MySQL, or do I need scripting lang. to sort it out?
Thoughts anyone?

OK
I must have had a temp. black out.
Here it is:
select x.id_a, x.name, z.id_b, z.id_a, z.condition from Table A
LEFT JOIN Table z ON x. id_a = z. id_a AND z.condition=1
condition below
AND z.condition=1
was the key, when placed in join condition not in where clause

Related

SQL join two tables using the maximum values

I have these two tables A and B:
Table A:
|--------------|----------------|
| ID_A |other attributes|
|--------------|----------------|
| 1 | |
| 2 | |
| 3 | |
| 4 | |
|--------------|----------------|
Table B:
|--------------|----------------|----------------|----------------|
| ID_B | ID_A | update_time |other attributes|
|--------------|----------------|----------------|----------------|
| 1 | 2 |2017/01/01 07:00| |
| 2 | 2 |2017/01/01 11:00| |
| 3 | 2 |2017/01/01 13:00| |
| 4 | 2 |2017/01/01 08:00| |
| 5 | 2 |2017/01/01 06:00| |
| 6 | 3 |2017/01/01 12:00| |
| 7 | 3 |2017/01/01 13:00| |
| 8 | 4 |2017/01/01 17:00| |
|--------------|----------------|----------------|----------------|
Now I want to get the latest update time (from table B) for every row in table A. If there is no relation between table A and table B, I want to show NULL. The desired result for the upper tables is:
|--------|----------------|
| ID_A | update_time |
|--------|----------------|
| 1 | NULL |
| 2 |2017/01/01 13:00|
| 3 |2017/01/01 13:00|
| 4 |2017/01/01 17:00|
|--------|----------------|
Is there any way how to do this in SQL? Also some explanation would be fine. Thanks for any help!
Use a LEFT JOIN. This will return ONLY the matching values from Table B and keep all the values from Table A.
The subquery of LEFT JOIN will Return ALL values with ID_A and their MAX value of Update_DateTime.
Select a.ID_A
b.Update_Time
FROM TABLE A A
LEFT JOIN (Select ID_A, max(Update_Time) as Update_Time
FROM TABLE B
Group by ID_A) B on B.ID_A = A.ID_A

MySQL - select results from a secondary table as a column in a primary table

I have a set of data consisting of two tables: table one is a set of unique items, and table two is a log of references that link the items in the first table together. For example:
Table one
+------------+--------------------+
| id | name |
+------------+--------------------+
| 1 | Item 1 |
| 2 | Item 2 |
| 3 | Item 3 |
| 4 | Item 4 |
| 5 | Item 5 |
+------------+--------------------+
Table two
+------------+--------------------+
| item_1_id | item_2_id |
+------------+--------------------+
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
| 2 | 4 |
| 2 | 5 |
+------------+--------------------+
Is it possible to group the rows that are in table two, and display them in some sort of array/collection as a column in table one. So based on my example tables, I would hope to return something like this:
+------------+-----------+----------+
| id | name | results |
+------------+-----------+----------+
| 1 | Item 1 | 2, 3, 5 |
| 2 | Item 2 | 1, 4, 5 |
| 3 | Item 3 | 1 |
| 4 | Item 4 | 2 |
| 5 | Item 5 | 1, 2 |
+------------+-----------+----------+
You can use group_concat for show the aggregated result and a select union for obtain both the related item for grouping
select id, name, group_concat( item1)
from table_one
left join
(select item_1_id as item1, item_2_id as item2
from table_two
union
select item_2_id , item_1_id
from table_two
order by item1) t1 ont1.item1 = table_one.id
group by id, name

Merge 2 different mysql tables

I have two tables:
Table a:
+----+------+
| id | data |
+----+------+
| 1 | 450 |
| 2 | 500 |
| 3 | 550 |
| 4 | 600 |
| 5 | 650 |
+----+------+
Table b:
+----+------+------+
| id | a_id | note |
+----+------+------+
| 1 | 2 | 25 |
| 2 | 5 | 10 |
+----+------+------+
I need a query that returns a table that consists of every row from table a with the notes from table b. I want 0 filled in where a note isn't available on a row. I want it to look like this:
+----+------+------+
| id | data | note |
+----+------+------+
| 1 | 450 | 0 |
| 2 | 500 | 25 |
| 3 | 550 | 0 |
| 4 | 600 | 0 |
| 5 | 650 | 10 |
+----+------+------+
How do I do that?
select a.id, a.data, coalesce(b.note, 0) as note
from a
left join b on a.id = b.a_id
What are you looking for is called LEFT/RIGHT JOIN. This question will give you more details about what they are.
Assume you have a query like:
SELECT * FROM a LEFT JOIN b ON some_condition;
Then, its output will contain every row from table a, along with data from table b where the condition is met. For rows where the condition is not met, the columns with data from b will contain null.

Mysql select row based on multiple rows in same table

I have the following table structure:
item_id | value |
==================
1 | 1 |
1 | 3 |
1 | 4 |
2 | 2 |
2 | 3 |
2 | 4 |
2 | 5 |
3 | 1 |
3 | 5 |
3 | 6 |
4 | 1 |
4 | 3 |
4 | 4 |
4 | 5 |
I have a query that returns those item_id whose value matches with 1, 3 and 4.
So here, the item_ids that should be returned are 1 and 4.
My query:
select item_id from table t
where exists (select item_id from table t1 where value = 1 and t1.item_id = t.item_id)
and exists (select item_id from table t1 where value = 2 and t1.item_id = t.item_id) group by item_id
This query is working fine. Here i am matching only 3 values. What if i want to match 50 such values from the table? (all the 50 values are stored in a php array) The query will be huge and also i want to do the same thing from two different tables in the same query. So, this will double the size of an already huge query. Please suggest me some other way around.
Edited::
table 2
--------
item_id | user_id |
==================
1 | 1 |
1 | 5 |
1 | 7 |
2 | 2 |
2 | 3 |
2 | 4 |
2 | 5 |
3 | 1 |
3 | 5 |
3 | 6 |
4 | 1 |
4 | 3 |
4 | 4 |
4 | 5 |
Now, i want item_id where values from table1 are 1,3,4 and user_id from table2 are 1,5,7
This problem is called Relational Division.
SELECT item_ID
FROM tableName
WHERE value IN (1,3,4)
GROUP BY item_ID
HAVING COUNT(*) = 3
if uniqueness was not enforce on column value for every item_id, DISTINCT is required to count only unique values,
SELECT item_ID
FROM tableName
WHERE value IN (1,3,4)
GROUP BY item_ID
HAVING COUNT(DISTINCT value) = 3
SQLFiddle Demo (both query included)
SQL of Relational Division

mysql getting data and looking it up in another table

I've got two tables in my database. Table 1 is a list of "timelines" and their corresponding owners and title.
Table 2 is a list of users who have access to the timelines but are followers, not owners.
I'm trying to write a query that outputs the lineID's and corresponding titles that are linked to a userID in either of the two tables.
A query for userID 1 would ideally output:
1 a
2 b
3 c
6 f
Hopefully this isn't too confusing but the purpose is to fill a dynamically generated select box with the LineID and Title for a given UserID...
Table 1 ("owners")
--------------------------
| LineID | UserID | Title |
| 1 | 1 | a |
| 2 | 1 | b |
| 3 | 1 | c |
| 4 | 2 | d |
| 5 | 2 | e |
| 6 | 1 | f |
--------------------------
Table 2 ("followers")
----------------------------
| RowID | LineID | UserID |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 3 | 1 |
| 4 | 3 | 2 |
| 5 | 2 | 2 |
| 6 | 6 | 1 |
----------------------------
I tried using:
SELECT title
FROM `lines`
LEFT JOIN follow
ON follow.user_id = lines.user_id
WHERE follow.user_id = 1
That ended up producing duplicate rows.
The output I need would ideally be an array consisting of all the lineID's and Titles associated with that userID.
select LineId, Title
from owners
where LineId in (select LineId from followers group by LineId )
order by owners.LineId