JOIN rows from 3 tables WHERE tableA.column1 = tableB.column1 = tableC.column1 - php

I have 3 tables, structured like so:
TABLE A:
ID | PCID | ACTIVE | COHORT | WEEKLY_MEETING_TIME | FYE_ID | RC | AGREEMENT_SIGNED | RELEASE_SIGNED | NOTES | FACULTY_ADVISOR
TABLE B:
ID | QUARTER | OFFICE | WRITING_CENTER | etc.. | etc.. | etc.. |
TABLE C:
ID | QUARTER | WEEK | EMAIL | etc.. | etc.. | etc.. |
The common element between all 3 tables is the ID field.
I need to SELECT from all 3 tables, and have each row represent one ID and all the values associated with that ID.
So, for example, each output row should look like a combination of the three tables:
RESULTS:
ID | PCID | ACTIVE | COHORT | WEEKLY_MEETING_TIME | FYE_ID | RC | AGREEMENT_SIGNED | RELEASE_SIGNED | NOTES | FACULTY_ADVISOR | QUARTER | OFFICE | WRITING_CENTER | etc.. | etc.. | etc.. | WEEK | EMAIL | etc.. | etc.. | etc.. |
I have no idea how to structure a query like this. I suspect it involves using JOINs but my attempts have proved futile.
how can I combine the data from 3 tables, based on shared ID field?

SELECT * FROM TABLEA
INNER JOIN TABLEB ON TABLEA.ID = TABLEB.ID
INNER JOIN TABLEC ON TABLEA.ID = TABLEC.ID
If you don't need all the values substitute the "*" with the names of the fields you need (ex. TABLEA.ID, TABLEB.QUARTER, TABLEC.WEEK...)

NATURAL JOIN works in MySQL:
select * from A natural join B natural join C

Try this :
SELECT / WHAT YOU NEED TO SELECT - NOT * !!!/
FROM TABLEA
INNER JOIN TABLEB USING (ID)
INNER JOIN TABLEC USING (ID)

Related

PDO Query : Count related and repeated values then inner join

I work with PHP and PDO.
So I have 2 tables like,
Table 1
| id | name | age |
| 1 | John | 25 |
| 2 | Tom | 32 |
| 3 | James| 45 |
Table 2
| id | Comment | Link |
| 1 | some text | 3 |
| 2 | some text | 3 |
| 3 | some text | 1 |
So, Link column numbers represent id's in table1. For example Link = 3s in table 2 represent James in table 1. I need a query which brings all table1's data and also a number of repeated value for related Link column which comes from table2.
For example, the query should give me (let's choose James),
| id | name | age | Value |
| 3 | James | 45 | 2 |
value=2, because there are two 3s in link column which related to James
I tried somethings but got lots of errors.
I think you just need the GROUP BY
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
GROUP BY a.id, a.name, a.age
If you really want just one row then add WHERE
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
WHERE a.name = 'James'
GROUP BY a.id, a.name, a.age
or use subquery
SELECT a.id,
a.name,
a.age,
(SELECT count(*) FROM table2 b WHERE a.id = b.link) as value
FROM table1 a
WHERE a.name = 'James'

MySQL - inner join - add column with value based on other value

I'm struggling with mysql joins :/
I've multiple tables inside database fe. tasks, users etc.
Table tasks containing tasks with various variables, but the most important - id's of users signed to task (as different roles inside the task - author, graphic, corrector):
+---------+-------------+--------------+
| task_id | task_author | task_graphic |
+---------+-------------+--------------+
| 444 | 1 | 2 |
+---------+-------------+--------------+
Table users
+---------+----------------+------------+-----------+
| user_id | user_nice_name | user_login | user_role |
+---------+----------------+------------+-----------+
| 1 | Nice Name #1 | login1 | 0 |
+---------+----------------+------------+-----------+
| 2 | Bad Name #2 | login2 | 1 |
+---------+----------------+------------+-----------+
Using PDO I'm getting the whole data I want while using INNER JOIN with data from different tables (and $_GET variable)
SELECT tasks.*, types.types_name, warehouse.warehouse_id, warehouse.warehouse_code, warehouse.warehouse_description
FROM tasks
INNER JOIN types ON types.types_id = tasks.task_id
INNER JOIN warehouse ON warehouse.warehouse_id = tasks.task_id
WHERE tasks.task_id = '".$get_id."'
ORDER BY tasks.task_id
Above query returns:
+---------+--------------+--------------+----------------+------------+-----------+------------------+------------------------+------------+-------------+-----------------+-----------+----------------+--------------------+---------------------+-----------+---------------------+------------------+---------------------+
| task_id | task_creator | task_graphic | task_purchaser | task_title | task_lang | task_description | task_description_files | task_files | task_status | task_prod_index | task_type | task_print_run | task_print_company | task_warehouse_code | task_cost | task_time_added | task_deadline | task_date_warehouse |
+---------+--------------+--------------+----------------+------------+-----------+------------------+------------------------+------------+-------------+-----------------+-----------+----------------+--------------------+---------------------+-----------+---------------------+------------------+---------------------+
| 2 | 1 | 2 | 1 | Test | PL | Lorem ipsum (?) | | | w | 2222 | 3 | 456546 | Firma XYZ | 2 | 124 | 29.09.2016 15:48:20 | 01.10.2016 12:00 | 07.10.2016 14:00 |
+---------+--------------+--------------+----------------+------------+-----------+------------------+------------------------+------------+-------------+-----------------+-----------+----------------+--------------------+---------------------+-----------+---------------------+------------------+---------------------+
And I'd like to get query with added user_nice_name after task_creator, task_author and task_graphic - obviously nice names selected from table users based on ID's provide in 3 above fields fe.
+---------+--------------+------------------------------------+--------------+--------------------------------------+
| task_id | task_creator | task_creator_nn | task_graphic | task_graphic |
+---------+--------------+------------------------------------+--------------+--------------------------------------+
| 2 | 1 | Nice Name (from task_creator ID=1) | 2 | Nice Name (from task_graphic ID = 2) |
+---------+--------------+------------------------------------+--------------+--------------------------------------+
How can I achieve that?
You need three joins:
SELECT t.*,
uc.user_nice_name as creator_name,
ug.user_nice_name as graphic_name,
up.user_nice_name as purchaser_name,
ty.types_name, w.warehouse_id, w.warehouse_code, w.warehouse_description
FROM tasks t INNER JOIN
types ty
ON ty.types_id = t.task_id INNER JOIN
warehouse w
ON w.warehouse_id = t.task_id LEFT JOIN
users uc
ON uc.user_id = t.task_creator LEFT JOIN
users ug
ON ug.user_id = t.task_graphic LEFT JOIN
users up
ON up.user_id = t.task_purchaser
WHERE t.task_id = '".$get_id."'
ORDER BY t.task_id;
Notes:
Table aliases make the query easier to write and to read. They are also required because you have three references to users in the FROM clause.
This uses LEFT JOIN for the users in case some of the reference values are missing.
You need to work on your naming. It doesn't make sense that a "warehouse" id matches a "task" id. Or that a "task" id matches a "types" id. But that is how you phrased the query in your question.
The ORDER BY effectively does nothing, because all rows have the same task_id.
Assuming that the task_graphic_name is inside a table name task_graphic_table and the relation field are task_graphic_id
SELECT tasks.*
, types.types_name
, warehouse.warehouse_id
, warehouse.warehouse_code
, warehouse.warehouse_description
, users.user_nice_name
FROM tasks
INNER JOIN types ON types.types_id = tasks.task_id
INNER JOIN warehouse ON warehouse.warehouse_id = tasks.task_id
INNER JOIN users ON users.user_nice_name = tasks.task_graphic
WHERE tasks.task_id = '".$get_id."'
ORDER BY tasks.task_id
And if you need the column appear in a specific order you should explicitally call the column name in sequence eg:
SELECT tasks.col1
, task.col2
, types.types_name
, warehouse.warehouse_id
, warehouse.warehouse_code
, task.col2
, warehouse.warehouse_description
, task_graphic_table.task_graphic_name
Add two sub query in with your query. like
SELECT tasks.*,
....
....,
(select user_nice_name from users where id = tasks.task_author) AS task_creator_name,
(select user_nice_name from users where id = tasks.task_graphic) AS task_graphic_name
FROM tasks
INNER JOIN types ON types.types_id = tasks.task_id
....
....

MYSQL statement: lookup how many records exist how many times in other table

I have 2 database tables:
Table 1:
+---------+-------+-------------+
| Page | Title | Description |
+---------+-------+-------------+
| Apple | ..... | ........... |
| Orange | ..... | ........... |
| Pear | ..... | ........... |
| Grapes | ..... | ........... |
+---------+-------+-------------+
Table 2:
+----------+-------------+
| Link | Page |
+----------+-------------+
| Website1 | Apple |
| Website2 | Orange |
| Website3 | Apple |
| Website4 | Orange |
| Website5 | Apple |
| Website6 | Pear |
| Website7 | Apple |
| Website8 | Grapes |
| Website9 | Grapes |
+----------+-------------+
I want to know/return how many pages from Table 1 are referenced in Table 2 and how many times they are referenced. (I DON'T want to know how many times EACH page in Table 1 is referenced in Table 2).
So in this example:
1 page is referenced 1 time (Pear),
2 pages are referenced 2 times (Grapes and Orange) &
1 page is referenced 4 times.
What kind of SQL statement would I use to get this?
Following query should do..
SELECT COUNT(1) NoOfPages,CNT ReferencedTimes
FROM
(
SELECT T2.PAGE,COUNT(1) CNT
FROM TABLE1 T1 INNER JOIN TABLE2 T2 ON T1.PAGE = T2.PAGE
GROUP BY T2.PAGE
)T
GROUP BY CNT
I think the following statement will fit:
SELECT count(*) FROM Table2 WHERE (Table2.Page IN (SELECT Page FROM Table1));
Use This query
Select table2.page,cnt(table2.page)
from table1 inner join table2
On table1.Page=table2.Page group by table2.page
SELECT (GROUP_CONCAT(DISTINCT page)) AS Page,page_count
FROM
(SELECT table1.Page as page,COUNT(*) as page_count
FROM table1 INNER JOIN table2 ON table1.Page=table2.Page
GROUP BY table1.Page)
as T GROUP BY page_count
Hope this helps
If what you are seeking is X page was referenced N times, the below query will achieve that:
SELECT COUNT(t1.page), t2.count
FROM table1 t1
INNER JOIN (SELECT page,COUNT(*) AS count FROM table2 GROUP BY page) t2 ON t1.page=t2.page
GROUP BY t2.count
Try this query, it will make a left join and tell you how many times item is referenced in table2, if count is zero than no reference in the other table
SELECT table1.Page, count(table2.Page) as count
FROM table1
LEFT JOIN table2 ON table2.Page = table1.Page
GROUP BY table1.Page

alternative to join 3 tables without repeticions

I have 3 tables in mysql, table A, B and C.
C has a relationship with B (b_id) and B has a relationship with A (a_id).
that means A has many B, and B has many C. To select all, I have this query:
SELECT a.id, a.name, a.text, b.ptext, c.ctext
FROM tableA as a
JOIN
tableB as b
ON
(b.p_id = a.id)
JOIN
tableC as c
ON
(c.p_pid = b.pid)
WHERE a.id = 1
which returns this:
| ID | NAME | TEXT | BTEXT | CTEXT |
|----|-------|--------------|--------|--------|
| 1 | page1 | futkdvthsa_1 | post_1 | thing1 |
| 1 | page1 | futkdvthsa_1 | post_2 | thing2 |
| 1 | page1 | futkdvthsa_1 | post_2 | thing3 |
is there any chance of getting something like this:
id | name | text | posts
1 | page1 | futkdvthsa_1 | posts (post_1 = ( thing1 ), post_2 = ( thing2, thing3 ) )
Sigle queries for each table or would need to do in a php way?
P.S. this would be for a wordpress plugin with custom tables.
I guess the simplest way to do this is by doing it with php.
You would have to use a stored procedure to concatenate your fields with sql.

Comparing values of columns from 3 tables - MySQL

following question:
I'm working with 3 tables = actors, movies, roles. I'm trying to find all the movies a given actor, say 'Robin Williams' has been in by comparing the specific actor id since there be may more than one actor with the same name. The actors table has the following relevant columns: first_name, last_name, id - the movies table has columns: id (the movie's id) - and the roles table has: actor_id and movie_id.
Do I JOIN the tables or use UNION? How do I compare columns from different tables when the columns have different names?
Thank you!
Just for reference:
Table actors:
mysql> SELECT *
-> FROM actors;
+--------+--------------------+------------------------+--------+------------+
| id | first_name | last_name | gender | film_count |
+--------+--------------------+------------------------+--------+------------+
| 933 | Lewis | Abernathy | M | 1 |
| 2547 | Andrew | Adamson | M | 1 |
| 2700 | William | Addy | M | 1 |
Table movies:
mysql> SELECT *
-> FROM movies;
+--------+------------------------------+------+------+
| id | name | year | rank |
+--------+------------------------------+------+------+
| 10920 | Aliens | 1986 | 8.2 |
| 17173 | Animal House | 1978 | 7.5 |
| 18979 | Apollo 13 | 1995 | 7.5 |
Table roles:
mysql> SELECT *
-> FROM roles;
+----------+----------+-------------------------------+
| actor_id | movie_id | role |
+----------+----------+-------------------------------+
| 16844 | 10920 | Lydecker |
| 36641 | 10920 | Russ Jorden |
| 42278 | 10920 | Cpl. Dwayne Hicks |
At first I tried setting each check equal to a PHP variable and comparing them but that seemed wrong, then I tried:
mysql> SELECT roles.actor_id, roles.movie_id, movies.id, actors.id
-> FROM roles
-> JOIN movies, actors
-> ON roles.actor_id = actors.id && roles.movie_id =movies.id;
which again does not work.
Finally figured it out..
>SELECT m.name, m.year
-> FROM movies m
->JOIN roles r ON m.id = r.movie_id
->JOIN actors a ON a.id = r.actor_id
->WHERE a.first_name = "whatever actor's first name"
->AND a.last_name = "whatever actor's last name"
This will then give you two columns with the corresponding name and year! hazzah!
First Read this answer - it made it click for me finally after years of unions when should join and vice versa.
In this case you should definitely JOIN as you want the result to act as a single row.
(think of it like this - I want to see Movie, Actor -> together as one result)
PS
You don't need your film count field any more as once you have the joins worked out you can just use MySQL COUNT -> it will make it easier to maintain.
You need a join. Try this:
SELECT A.first_name,A.last_name,A.gender,M.name,M.year,M.rank,R.role
FROM roles R INNER JOIN
Movies M ON R.movie_id = M.movie_id INNER JOIN
Actors A ON R.actory_id = A.id

Categories