SQL - Join Three Tables with common link in third table - mysql

Before I begin, Yes, I thoroughly tried searching for many tutorials on JOINS/INNER JOINS/OUTER JOINS/FULL JOINS but I'm not exactly sure what I'm looking for so a little guidance or simply a finger pointing me in the correct direction would be very helpful. I'll try to be as clear as possible.
So basically, I have Three tables
Foo
| FooID | name | data |
1 Name1 Data1
2 Name2 Data2
3 Name3 Data3
4 Name4 Data4
Bar
| BarID |
1
2
Matrix
| BarID | FooID|
1 2
1 3
1 4
2 1
2 3
So what I'm looking for is, I basically have BarID (let's just pretend it's 1 for clarity purposes). I want to get all the rows from table Matrix that correlate to BarID, so that way I can retrieve the rows that it relate to in Foo (For example, BarID = 1, so I should get rows 2, 3 and 4 in Foo and if BarID is 2, I will get 1 and 3, and so on).
I was trying something similar to:
SELECT Foo.FooID, Foo.name, Foo.data
FROM Bar
JOIN Matrix ON Matrix.BarID = 1 // The 1 is passed in, in this example
JOIN Foo ... // And this is where I'm stuck
Does this make sense what I'm trying to accomplish? I know it's weird. Will appreciate any assistance pointing. Thank you in advance!

You seem to want a simple JOIN and WHERE
select f.*
from foo f join
matrix m
on f.fooid = m.fooid
where m.barid = 1;
You do not need the bar table, because you are passing in the id. I think you might have been overthinking the problem.

Related

add two table per row based on its name

I have two tables and i want to add there row based on its name. I've search on net but I only found how to combine the total value or two tables and combine them. The result will be added on a table named Result
Table 1 Table 2 Result
Name | Value Name | Value Name | Value
Apple | 2 Apple | 4 Apple | 6
Orange | 3 Orange | 2 Orange| 5
Thank you in advance
First of all I would like to say you must try to get solution at your own.
For your case, answer is very simple. Try this query :
SELECT table1.`name`, (table2.value + table1.value) AS `value` FROM table1
LEFT JOIN table2 ON table1.`name` = table2.`name` WHERE table1.`name` = table2.`name`

postgresql, select multiple json_array_elements works so werid

I want use json_array_elements to expands json array. But it works so werid. Pls see below.
select json_array_elements('[1, 2]') as a, json_array_elements('[2, 3, 4]') as b;
a | b
---+---
1 | 2
2 | 3
1 | 4
2 | 2
1 | 3
2 | 4
(6 rows)
select json_array_elements('[1, 2]') as a, json_array_elements('[2, 3]') as b;
a | b
---+---
1 | 2
2 | 3
(2 rows)
It's seems when the length of the arrays are equal, something goes wrong.
Can anyone tell me, why is like this.
PostgreSQL repeats each list until both happen to be at the end simultaneously.
In other words, the length of the result list is the least common multiple of the length of the input lists.
This behaviour is indeed weird, and will be changed in PostgreSQL v10:
select json_array_elements('[1, 2]') as a, json_array_elements('[2, 3, 4]') as b;
a | b
---+---
1 | 2
2 | 3
| 4
(3 rows)
From the commit message:
While moving SRF evaluation to ProjectSet would allow to retain the old
"least common multiple" behavior when multiple SRFs are present in one
targetlist (i.e. continue returning rows until all SRFs are at the end of
their input at the same time), we decided to instead only return rows till
all SRFs are exhausted, returning NULL for already exhausted ones. We
deemed the previous behavior to be too confusing, unexpected and actually
not particularly useful.

Select multiple values from different rows on table_a into one new row on table_b

I have a table like below:
'table_a'
Type | Value
-----+------------
000 | 100020003
001 | 004
002 | 5000600070008
I need to end up with a result set that is like below:
'table_b'
---+---+---+---
1 | 2 | 3 | 4 ETC...
I have used substring to pull 1, 2, and 3 where type = 000. Now I need to do the same with type 001 and 002 but how can they be joined together to create one row in 'table_b'?
So far I have used the below to populate 1, 2 and 3 but I have no idea how to select the data from the remaining rows.
SELECT SUBSTRING(Value,1,1) AS val_1
SUBSTRING(Value,5,1) AS val_2
SUBSTRING(Value,9,1) AS val_3
FROM table_a
WHERE type = 000
Next query would be like this:
SELECT SUBSTRING(Value,3,1) AS val_4
FROM table_a
WHERE type = 001
So as you can see I cannot use a union because I am not selecting the same number of items in each select statement.
The data I am pulling from is not this uniform but hopefully this conveys what I need to do correctly. I greatly appreciate any assistance.
SELECT SUBSTRING(Value,1,1) || "val_1",
SUBSTRING(Value,5,1) || "val_2",
SUBSTRING(Value,9,1) || "val_3",
FROM table_a
WHERE type = 000

MySQL Reciprocal Search

I have a table which stores the edges of a directed graph like so:
Table EDGES
FROM_NODE | TO_NODE | STRENGTH
1 | 1 | 8
1 | 2 | 5
2 | 1 | 4
1 | 3 | 2
3 | 4 | 1
And I'm trying to search for edges which are supported in both directions with strength > 3. In the example above, 1 -> 2 and 2 -> 1 both exist, however, 1 <-> 3 does not exist in both directions. 1 -> 1 doesn't count, for obvious reasons.
The major complication is that there are over 1,000,000 edges to search, and all the queries I have tried so far fail before I can check if they've worked.
Any suggestions would be greatly appreciated!
To me the most straightforward solution is something like:
select one.from_node, one.to_node
from edges one
join edges other on (one.to_node = other.from_node AND one.from_node = other.to_node)
where one.strength > 3 AND other.strength > 3
AND one.from_node <> one.to_node
If you have a lot of data, than it's might be a good idea to reconsider indexes on the table and raise the execution limit.
Here is an sql fiddle to check the query.
I think you can use something like this:
select
least(FROM_NODE, TO_NODE) as n1,
greatest(FROM_NODE, TO_NODE) as n2
from
edges
where FROM_NODE<>TO_NODE and nodes.strength>3
group by n1, n2
having count(*)=2

SSRS report formatting a table to display data side by side

I am trying to achieve the following layout for my report based on one query.
+----+-------+----+-------+
| ID | Name | ID | Name |
+----+-------+----+-------+
| 1 | Danny | 2 | Dave |
| 3 | Sue | 4 | Jack |
| 5 | Rita | 6 | Sarah |
+----+-------+----+-------+
So I basically want one table, printing my data from left to right to save space on my page, rather than it printing one line and wasting all of the space on the right side of the paper, possibly even go 3 times across the width.
This is my data: http://sqlfiddle.com/#!3/5c911/1
I was maybe thinking a table with 4 columns. Cols 1 and 2 contain the odd row numbers, Cols 3 and 4 contain the even row numbers.
How could I achieve this, I did try something with the MOD function but it didn't seem to work properly, or I misunderstood what was happening.
Related:
How can I display two rows worth of data on one line side-by-side in Report Designer?
Thanks,
To print your data from left to right in a multi-column format, you need to fake it using multiple tables. To implement this hack, create the same number of tables as columns you want side by side that all point to your data set. On the Detail row of the first table, for the Visibility-Hidden property use the following formula:
=IIF((RowNumber(Nothing) Mod 4) = 1, False, True)
where 4 is the number of tables (columns) you have.
Do the same for each table, incrementing what the formula is equal to (so for the second column (RowNumber(Nothing) Mod 4) = 2 and so forth). In the last table (column) the formula equals 0.
This alternately hides the detail row, only displaying the appropriate rows for that column number.
You can achieve that look with query.
SELECT std1.id AS Student_Id,
std1.NAME AS Student_Name,
std2.id AS Student_Id,
std2.NAME AS Student_Name
FROM students std1, students std2
WHERE (std2.id - std1.id = 1
AND std1.id %2 = 1);