Joining SQL queries with where clause - sql

I have 2 tables in a MYSQL database wich look like this:
Klant:
ID Naam Email Soort Status
6 test test test2
7 status test test test 20
8 soort test test test
9 soort test 2 test2 Museum
Mail:
ID Content Datum Titel
1 (lots of encoded HTML) 18-03-13 test
2 (lots of encoded HTML) 18-03-13 test2
4 (lots of encoded HTML) 18-03-13 alles weer testen
(yes, I'm still testing alot^^)
Now I have a SQL query that selects all from 'Klant' with a where clause which gets the ID from a previous page:
$strSQL = "SELECT * FROM Klant WHERE ID = '".$_GET["ID"]."' ";
What I want is to JOIN this query with the following query:
SELECT ID, Titel FROM Mail;
EDIT:
From all your answers and comments I think I begin to think my question maybe is totally wrong.. I'll explain where I need it for and I might not even need JOIN? I currently have a table wich includes the data from 'Klant' which looks like this:
The meaning is that I add another table which includes all the ID's and Title's from 'Mail'. I am sorry for the confusion I may have caused with you since I wasn't that clear with my question. I hope that this may clear up what I want and you guys can maybe tell me if I even need to JOIN this or can I do something else?
I am still a student and this is the first time I've had to use JOIN and I can't figure this out. If anyone can show me how to do this or push me in the right direction it would be great!

SELECT * FROM Klant t1
JOIN
SELECT ID, Titel FROM Mail t2
ON t1.ID = t2.ID
WHERE t1.Name = 'test'
To have the desired result do the following:
SELECT * FROM Klant t1
JOIN
SELECT ID, Titel FROM Mail t2
ON t1.ID = t2.ID
And if you want to have a specific row than just add the where clause:
WHERE t1.ID = 6
or
WHERE t1.Naam = 'test'
and so on

It is difficult to see how a JOIN is applicable in the example in your question.
A JOIN let's you pull information from more than one table based on a relationship. As far as I can see, your table's don't have any way to link a row in one with a row in the other, unless SteveP is correct and your id's provide that relationship.
For example, if your klant table had a mail_id column then you could do
SELECT *
FROM klant
JOIN mail ON klant.mail_id = mail.id
and this would return a row for every matching pair of rows in the two tables. Alternatively you could use a LEFT OUTER JOIN to pull back all rows from the table on the left of the JOIN and optionally data from a matching row on the right.
If there is nothing joining the table, you can use a CROSS JOIN which will return you a full cartesian of each row in table1 with every row in table2.
Something people often confuse with a JOIN is a UNION which allows you to write 2 SELECT statements and return the result set of both combined/joined together, but these should return the same columns in each query (e.g. selecting NULL in place of the column in a query if the query doesn't pull data for that column)

I'm guess that you want to join on the ID field which is common between the tables.
select * from Klant, Mail where Klant.ID = '".$_GET["ID"]."' and Klant.ID = Mail.ID
You can also do
select * from Klant
join Mail on Mail.ID = Klant.ID
where Klant.ID = '".$_GET["ID"]."'

You can do this directly by using the following query :
select k.ID,k.Naam, k.Email,k.Soort,k.Status, m.ID,m.Titel from Klant k, Mail m where k.ID = m.ID and k.ID = '".$_GET["ID"]."'

Related

SQL IN statement with multiple conditions and 3 tables

I have just learned IN and NOT IN statements in SQL. I understand statements like
SELECT * FROM table1 WHERE table1.attribute IN
(SELECT table2.attribute FROM table2 WHERE attribute = condition);
My problem is I need to show 3 columns (from two different tables) using an IN (SELECT) statement with a 3rd table with a condition from that 3rd table only and another condition from one of the first two tables.
Example:
Show name(table1), class(table1), course(table2) where course LIKE "cosc%" (table 2) and grade = 'b' (table 3). I need to USE an IN statement.
My attempt:
SELECT stud.sname, stud.class, sec.course_num FROM stud, sec
WHERE sec.course_num LIKE 'COSC%'
AND stud.stno IN
(SELECT gr.student_number FROM gr WHERE gr.grade = 'B');
Table3 shares a domain with both table1 and table2. This query resulted in way too many rows, there are only 48 rows in one of these tables. I know how to do all the JOIN statements, I don't need that.
Something like this, assuming stud refers to sec:
SELECT stud.sname, stud.class, sec.course_num
FROM stud JOIN sec ON stud.sec_id = sec.id
WHERE sec.course_num LIKE 'COSC%'
AND stud.stno IN (
SELECT gr.student_number FROM gr WHERE gr.grade = 'B'
)
;
It's possible the logic needs to be adjusted and that other logic is missing.
We'll see when the question is updated with the requested detail.

PDO Select from table WHERE url != (SELECT)

I have 2 db tables - one is including all the entries, the other one is the "blacklist" - means i want to select all values excluding the entries of table 2
$req = "SELECT * FROM table1 WHERE link_id != (SELECT id FROM table2)";
$stmt = $pdo->query($req);
foreach($stmt as $data) {
echo $data['link_id']."<br>";
}
Can anyone help me out?
You could try NOT IN, like so:
$req = "SELECT * FROM table1 WHERE link_id NOT IN (SELECT id FROM table2)";
I think that would do what you're asking for, if I understand you correctly. It may not be the fastest way to do it, though.
Although the selected answer works it is not efficient as the DB will need to do two seeks for the internal query and then again on the external query. The most efficient and effective query is a LEFT JOIN that removes the need for the second query.
SELECT b.* FROM names AS n LEFT JOIN blacklist_names AS b on n.id=b.id WHERE b.id IS NULL;
You can alias the tables like I did or not. I did it to make the code shorter.
What the query is doing is matching all ids found in both tables and then excluding them from the results by taking whats left from the "all names list" that is not in the blacklist.
EDIT: As per the author, putting the solution here to highlight it from the comments.
SELECT spotify.ID,spotify.land,spotify.song,spotify.link_id,spotify.pos1 FROM spotify LEFT JOIN spotify_blacklist ON (spotify.link_id = spotify_blacklist.URL) WHERE spotify_blacklist.URL IS NULL ORDER BY spotify.song ASC

Number of Records don't match when Joining three tables

Despite going through every material I could possibly find on the internet, I haven't been able to solve this issue myself. I am new to MS Access and would really appreciate any pointers.
Here's my problem - I have three tables
Source1084 with columns - Department, Sub-Dept, Entity, Account, +few more
R12CAOmappingTable with columns - Account, R12_Account
Table4 with columns - R12_Account, Department, Sub-Dept, Entity, New Dept, LOB +few more
I have a total of 1084 records in Source and the result table must also contain 1084 records. I need to draw a table with all the columns from Source + R12_account from R12CAOmappingTable + all columns from Table4.
Here is the query I wrote. This yields the right columns but gives me more or less number of records with interchanging different join options.
SELECT rmt.r12_account,
srb.version,
srb.fy,
srb.joblevel,
srb.scenario,
srb.department,
srb.[sub-department],
srb.[job function],
srb.entity,
srb.employee,
table4.lob,
table4.product,
table4.newacct,
table4.newdept,
srb.[beg balance],
srb.jan,
srb.feb,
srb.mar,
srb.apr,
srb.may,
srb.jun,
srb.jul,
srb.aug,
srb.sep,
srb.oct,
srb.nov,
srb.dec,
rmt.r12_account
FROM (source1084 AS srb
LEFT JOIN r12caomappingtable AS rmt
ON srb.account = rmt.account)
LEFT JOIN table4
ON ( srb.department = table4.dept )
AND ( srb.[sub-department] = table4.subdept )
AND ( srb.entity = table4.entity )
WHERE ( ( ( srb.[sub-department] ) = table4.subdept )
AND ( ( srb.entity ) = table4.entity )
AND ( ( rmt.r12_account ) = table4.r12_account ) );
In this simple example, Table1 contains 3 rows with unique fld1 values. Table2 contains one row, and the fld1 value in that row matches one of those in Table1. Therefore this query returns 3 rows.
SELECT *
FROM
Table1 AS t1
LEFT JOIN Table2 AS t2
ON t1.fld1 = t2.fld1;
However if I add the WHERE clause as below, that version of the query returns only one row --- the row where the fld1 values match.
SELECT *
FROM
Table1 AS t1
LEFT JOIN Table2 AS t2
ON t1.fld1 = t2.fld1
WHERE t1.fld1 = t2.fld1;
In other words, that WHERE clause counteracts the LEFT JOIN because it excludes rows where t2.fld1 is Null. If that makes sense, notice that second query is functionally equivalent to this ...
SELECT *
FROM
Table1 AS t1
INNER JOIN Table2 AS t2
ON t1.fld1 = t2.fld1;
Your situation is similar. I suggest you first eliminate the WHERE clause and confirm this query returns at least your expected 1084 rows.
SELECT Count(*) AS CountOfRows
FROM (source1084 AS srb
LEFT JOIN r12caomappingtable AS rmt
ON srb.account = rmt.account)
LEFT JOIN table4
ON ( srb.department = table4.dept )
AND ( srb.[sub-department] = table4.subdept )
AND ( srb.entity = table4.entity );
After you get the query returning the correct number of rows, you can alter the SELECT list to return the columns you want. But the columns aren't really the issue until you can get the correct rows.
Without knowing your tables values it is hard to give a complete answer to your question. The issue that is causing you a problem based on how you described it. Is more then likely based on the type of joins you are using.
The best way I found to understand what type of joins you should be using would referencing a Venn diagram explaining the different type of joins that you can use.
Jeff Atwood also has a really good explanation of SQL joins on his site using the above method as well.
Best to just use the query builder. Drop in your main table. Choose the columns you want. Now for any of the other lookup values then simply drop in the other tables, draw the join line(s), double click and use a left join. You can do this for 2 or 30 columns that need to "grab" or lookup other values from other tables. The number of ORIGINAL rows in the base table returned should ALWAYS remain the same.
So just use the query builder and follow the above.
The problem with your posted SQL is you NESTED the joins inside (). Don't do that. (or let the query builder do this for you – they tend to be quite messy but will also work).
Just use this:
FROM source1084 AS srb
LEFT JOIN r12caomappingtable AS rmt
ON srb.account = rmt.account
LEFT JOIN table4
ON ( srb.department = table4.dept )
AND ( srb.[sub-department] = table4.subdept )
AND ( srb.entity = table4.entity )
As noted, I don't see why you are "repeating" the conditions again in the where clause.

Join on ((= Statement) or ((!= Statement), other stipulations))

I have some information where the IdNumbers (not primary key Ids, just random Ids assigned to individuals) are not always correct in my first table.
Therefore I am joining my second table on both Ids and names, and trying to get it to where it will join on names only if the IdNumbers do not match.
I'm working on a query with a join statement that is roughly as follows (I'm leaving out the SELECT, WHERE, and ORDER BY sections because I believe that they are not having an effect on this issue and I don't want to be confusing, as they are stupidly complex - if the portion of the query below should be working like I want it to and the problem is obviously somewhere else, then just tell me so and that will answer my question):
FROM Table1
FULL OUTER JOIN Table2 ON ((Table1.IdNumber = Table2.IdNumber)
OR (Table1.IdNumber != Table2.IdNumber
AND Table1.Lname = Table2.Lname
AND Table1.Fname = Table2.Fname))
However, it is joining the people who have both matching Ids and matching names multiple times like so:
Fname M Lname Table1.IdNumber Table2.IdNumber2
Matthew - Smith 1 2
Matthew H Smith 2 1
Matthew - Smith 1 1
Matthew H Smith 2 2
So it is pulling the last 2 because their ids match, but also joining the first 2 because their ids do not match and their names match, but why is it even joining the first 2 to begin with? I suspect that it ignores the != statement when deciding where to join since the other conditions are fulfilled, but I'd like it to take this != statement into account somehow.
If this should be working, like I said before, just tell me and it will answer my question.
(*EDIT)
Sorry, I should have named these properly - I've revised the names. And the full outer join is necessary, I need everything from both tables no matter what and it's working fine, but thank you for the suggestion.
Given how messy this would be to do in one JOIN, I would suggest using a temp table to hold the relationships.
You can insert all of your IDs from the into first table into a temp table, then do two passes to update a column holding the 2nd table ID - first using where the ID matches, and second where the ID doesn't match but the name does.
You can then use this table to join the two tables, retrieving up to one record from table 2 for each record in table 1.
I think you want something like this:
select t1.*,t2.*
from t1,t2
where t1.id = t2.id
and t1.name = t2.name
union
select t1.*,t2.*
from t1,t2
where t1.id ! t2.id
Your query should work, if the columns are coming from the right tables. Because you are not using table aliases, I suspect that you have an expression such as:
fname1 = fname2
and both columns are in the same table. Or worse:
fname1 = fname1
which is essentially always TRUE (except when fname1 is not null).
Your query might work, but it will be inefficient in most databases, because they will use nested loop optimizations. Consider rewriting the query to be:
from table1 t1 full outer join
table2 byID
on t1.IdNumber = byID.IdNumber full outer join
table2 byName
on t1.fname = byName.fname and t1.lname = byName.lname and t1.idNumber <> byName.idNumber
This will require changing other clauses in your query, typically to something like:
coalesce(byId.column, byName.column) as Column

Selecting data from 2 different databases and comparing them

Forgive me if this question has already been asked, but... I'm trying to select data from 2 different tables in a database and count all the data in one table that is equal to the data in the second table if that makes sense? Below is the code I am trying to use
$select = "SELECT * FROM client_id, clientid, COUNT(client_id) FROM enquiry, check_s WHERE client_id = clientid";
Your query appears to be syntactically wrong.
What you can try is to join the two tables on a primary key(id?) and any other fields you're trying to match. The basic syntax would be like this:
SELECT * FROM
DB1.Table1
JOIN DB2.Table2
ON DB1.Table1.PrimaryKey = DB2.Table2.PrimaryKey;
If you're looking for an exact data match, you may have to join the tables based on all fields(in the ON clause in the above query).
Edit:
Now that you've explained it, you can try this:
SELECT table1.*, count(*) as `n` FROM table1
JOIN table2
ON table1.field = table2.field;
Again, if you need to compare more fields, just include them in the ON clause, and set conditions in the WHERE clause.
I think you might be looking for something like this:
Lets say your main table name is Client and your secondary table (from the form) is Enquiry and the column which you want to compare in client is called client_id and the same column in Enquiry is called clientid.
Then you have
Select Count(Client.*)
From Client, Enquiry
Where Client.client_id = Enquiry.clientid
Group by Client.client_id