How to check if similar values exist across multiple tables - php

I've read and reviewed numerous posts on here (and elsewhere) about how to do this, but my results seem to be working backwards from what makes sense.
I have 4 tables that have different columns/data, but the columns I need to select from are the same and have the same structure.
Table 1: | id | item_id | user | other table 1 specific columns...<br>
Table 2: | id | item_id | user | other table 2 specific columns...<br>
Table 3: | id | item_id | user | other table 3 specific columns...<br>
Table 4: | id | item_id | user | other table 4 specific columns...<br>
I am trying to check to see if a specific user/item_id combination exists across all 4 tables in 1 query instead of 4.
If I'm reading all the posts correctly, I should do a UNION ALL between the SELECT statements, however, I'm actually getting the reverse of what is making sense.
To keep things simple, I am just testing this with Table 1 and Table 2.
Table 1 does NOT have the combination I'm looking for.
Table 2 does have the combination I'm looking for.
SELECT item_id AS table1ID
FROM table1
WHERE item_id=35 AND user='usernamehere'
UNION ALL
SELECT item_id AS table2ID
FROM table2
WHERE item_id=35 AND user='usernamehere'
So, what I was expecting to see was a null result from Table 1 and a result with the item_id from Table 2, but what's happening is I'm getting no result at all from Table 2 and a "hit" from Table 1.
Seems backwards and confusing since Table 1 doesn't actually have a record with item_id=35 and user='usernamehere'.
Any advice or insights are greatly appreciated.

Your query is just listing item_id's in the specific table. It does not specify where they come from. For two table, you can solve the problem using a join.
I think for more tables, you will want something like this:
select item_id, group_concat(which order by which) as tables
from ((select item_id, user, 'table1' as which from table1) union all
(select item_id, user, 'table2' from table1) union all
(select item_id, user, 'table3' from table1) union all
(select item_id, user, 'table4' from table1)
) t
where user = 'usernamehere'
group by item_id;
For each item_id, this will list the tables it is in. If you want items in all four tables. then add a having clause:
having count(distinct which) = 4;
Similarly, if you want examples where one or more are missing:
having count(distinct which) < 4;

Assuming $var has your search field:
select
inp.ID,
count(t1.itemID) as TableOne,
count(t2.itemID) as TableTwo,
count(t2.itemID) as TableThree,
count(t3.itemID) as TableFour
from
(
select
".$var." as ID
from
dual
) inp
left outer join
table1 t1
on inp.ID=t1.item_id
left outer join
table2 t2
on inp.ID=t1.item_id
left outer join
table3 t3
on inp.ID=t1.item_id
left outer join
table4 t4
on inp.ID=t1.item_id
group by
inp.ID
This will give you a count of whether the item is in your tables via a select you create and outer joins to your other tables which you can count nicely.

UNION will merge results (rows), I don't think it's what you need.
Consider using JOIN statement:
SELECT exTable.ID
FROM exTable as t1
JOIN t2 as t2 ON t1.col = t2.col // we have value of col in t2 same as in t1
JOIN t3 as t3 ON t1.col = t3.col
JOIN t4 as t4 ON t1.col = t4.col
WHERE t1.ID = 35 AND t1.user = 'usernamehere'
In some cases you may use LEFT OR RIGHT joins, you can read about them on W3C.

Related

Query to fetch data from two different tables

I have two tables. Table A and B.
I have a log-in form where I will get the username,password, assign, assign2 of the user from table A and fetch data depending on the user's assign1 and assign2 from table B.
How my query would look like?
Looking for answers. Thankyou so much.
Table A -THIS IS THE TABLE FOR LOG-IN FORM
==========================================
username | password | assign1 | assign2 |
------------------------------------------
SANDRA | SANTOS | 1 | 1 | //Values
--------------------------------------------
Table B -
=======================================
name | assign1 | assign 2 |
------------------------------
DADA | 1 | 1 | //this will be displayed
------------------------------
gorg | 2 | 2 |
//this must not be displayed since the user assign1 and assign2 who logged in did not match to this
You are using $sql variable in
$result = $con->query($sql);
It should be $queryagain.
Your question is not clear, but if you want to fetch data from Table B which depends on assign1 and assign2 you can do it like this:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.name=tableA.username WHERE tableA.assign1 = tableB.assign1 AND tableA.assign2 = tableB.assign2");
When you use JOIN it's best practice to JOIN by primary key (id). If tableB.name=tableA.username are not columns with same value you can join by other columns, like assign1, or assign2:
assign1:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.assign1=tableA.assign1 WHERE tableA.assign2 = tableB.assign2");
assign2:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.assign2=tableA.assign2 WHERE tableA.assign1 = tableB.assign1");
Notice: Where clause is not necessay, you can edit WHERE clause depends of the result you want.
I think your are very very new to database programing. First of all I recomend you to read https://www.w3schools.com/sql/sql_join.asp this page and work on examples using try it yourself part.
Join Types:
INNER JOIN: Returns records that have matching values in both tables. That means if assign field is filled in Table A and the value is included in table B then this type of join should match the rows.
LEFT JOIN: Return all records from the left table, and the matched records from the right table. That means all rows in Table A will match either the value is included in table B or not.
RIGHT JOIN: Return all records from the right table, and the matched records from the left table. That means all rows in Table B will match either the value is included in table A or not.
FULL JOIN: Return all records when there is a match in either left or right table. All rows in table A and table B will be included in te result set either they match or not.
Your SQL query may look like:
$sql = "SELECT * FROM table_a a INNER JOIN table_b b on a.assign1 = b.assign1 INNER JOIN table_b b2 on a.assign2 = b2.assign2";
execution part of the sql can be different depending your database engine or other libraries.
I think this thread also helps you: Join two mysql tables with php

Join two tables on different columns

I have two tables like below in mysql
city
id from to
1 101 102
travel
id name
101 ABC
102 XYZ
I am trying to join table such that I will get ABC as source and XYZ as destination. I tried multiple combinations but not getting expected result
Join the travel table twice with different alias names
select c.id,
t1.name as city_from,
t2.name as city_to
from city c
join travel t1 on t1.id = c.`from`
join travel t2 on t2.id = c.`to`

Getting data from multiple tables into single row while

I'm trying to retrieve data from 2 tables and combine multiple rows into a single while loop
posts
post_id content
------ -------
1 content1
2 content2
3 content3
4 content4
comments
id post_id content
------ ------ ------
1 1 Wharton university
1 2 Yale University
sql code I write
mysqli_query( $connect, "SELECT * FROM `posts`
INNER JOIN comments ON posts.post_id = comments.post_id ORDER BY 1 DESC");
The problem I'm only getting post id 1 and 2. while there are over 30 posts
I want to get all posts and comments for each post in a single while loop.
How can I do it ?
Change your join to a LEFT join instead of an INNER join.
The difference being that a LEFT join will use null when there's no comments, where as INNER will only give you the rows that have comments.
Your INNER join is taking the union of both tables on the post_id field. You need a LEFT join instead of an INNER join. The LEFT join will give you all the results from the first table.

Getting records from more than 2 tables using join

Here is my table structure:
Table 1
id | question | posted_id
Table 2
id | username | email
Table 3
id | reader_id | quote_id
I want to fetch those question which are not read by particular user.I also want email from table2 in result set. So I created Below query that join my two table1 and table2.
My query:
SELECT table1.id,table1.question,table1.posted_id,table2.email
FROM table1,table2
WHERE table1.post_id = table.id;
How to fix a left join on table 3 for filter the records Because I need questions which are not read by particular user.
I am not sure which user field you are trying to match against, i have taken email, Also this will only give matching records, Try
SELECT T1.*,T2.email
FROM Table1 AS T1
INNER JOIN Table2 AS T2 ON T2.quote_id = T1.id
INNER JOIN Table3 AS T3 ON T3.reader_id = T2.id
WHERE T2.email='some_mail_id'

How to find rows in a MySQL database that don't correlate correctly with other rows

I have a table in my MySQL database that, in part, looks like this:
+----+-------+-------+
| id | owner | onwed |
+----+-------+-------+
| 1 | A | B |
| 2 | B | A |
| 3 | C | D |
| 4 | D | C |
| 5 | E | X |
+----+-------+-------+
They important feature here is that all the entries are paired, so that each "owner" is also "owned" by the record they correlate to. A "owns" B, and also B "owns" A. D "owns" C, and also C "owns" D.
However, in row 5,we have a problem. E "owns" X, but there is no entry for X "owning" E.
I need to be able to go through this table, which has thousands of records, and find all instances like row 5, where we have an orphaned record. Where there is no corralating with the "owner" and "owned" fields having a matched opposite. Also, there is no assurance that paired rows will follow each other as they do in my example.
This problem goes way beyond my MySQL abilities. I know how to do a search when I know what the value I'm looking for is. But I don't know how to go through each row one by one, take values out, and then use those values to do another search. I hope someone can help me out and I apologize that I'm so clueless on this matter that I don't have any code to suggest.
I'm not so worried about efficiency, in that this is a check I would only run every now and again when there is reason to suspect a problem. Also, if it helps, I manage my MySQL database from a PHP script, so if there is PHP code that can be leveraged to make the task more manageable, that could also be utilized.
What you need is a join. If you join the table on itself with the owned on owner.
SELECT T1.Id, T1.Owner, T1.Owned, T2.Id, T2.Owner, T2.Owned
FROM tablename T1
LEFT JOIN tablename T2
ON T1.Owned = T2.Owner
WHERE T2.Owned != T1.Owner
OR T2.Id IS NULL
Try to run the query without the WHERE clause to see what this join does. You get both owners and owned on a single row and then you can compare if they match.
You could try a query similar to (not sure about the backquotes of MySQL)
SELECT * FROM `table`
WHERE (`owner`,`owned`)
NOT IN (SELECT `owned`,`owner` FROM `table`);
There are probably cleaner solutions without selfjoins
There are better ways, but this will work:
SELECT
*
FROM
table
WHERE
id NOT IN (
SELECT
id
FROM
table s1
WHERE
s1.owner = (
SELECT
onwed
FROM
table s2
WHERE
s2.onwed = s1.owner
)
);
Its easy:
select t1.id from tableName as t1 left join tableName as t2
on t1.owner = t2.owned and t1.owned = t2.owner
where t2.id is null
select
*
from
mytable
where id not in (
select
m1.id
from
mytable m1,
mytable m2
where
m1.owner=m2.owned
)
You can try this- demo below :
http://sqlfiddle.com/#!2/0db47/7
SELECT a.id, a.owner, a.onwed
FROM TableName a
LEFT JOIN TableName b
ON (a.Owner = b.Owner AND a.Onwed = b.OnWed) OR
(a.Owner = b.OnWed AND a.Onwed = b.Owner)
GROUP BY a.id, a.owner, a.onwed
HAVING COUNT(*) = 1
SQLFiddle Demo

Categories