Checking two tables against each other in MySQL query - php

I feel like I'm writing a word problem, but it's really puzzling me and I really hope someone here can solve it:
I want to select one row from table A. Table A includes the attributes Name and Number. But before I finish the query, I want to check it against table B. Table B includes Name, Number, and the Username of the user.
Based on the users' input, it inserts rows into table B that include their Username along with a Name and Number.
Now in my query where I select a row from table A, I want to make sure that there are no rows in table B with matching Name and Number for that particular User.
I have tried WHERE (A.Name = B.Name AND A.Number = B.Number AND B.Username != '$username') but I think I was way off base with that.
Any help would be... amazing.

SELECT
A.id
FROM
A
LEFT OUTER JOIN B ON
(A.Name = B.Name AND A.Number = B.Number)
WHERE
B.Name IS NULL
AND B.Number IS NULL
AND B.Username = ?

select a.id
from a
where
a.name=:name
and
not exists(select 1 from b where b.id=a.id and b.name=a.name)

IF NOT EXISTS ( SELECT 1
FROM tableA a
INNER JOIN tableB b
ON a.name = b.name
AND a.number= b.number
AND b.UserName = 'user' and b.name = 'name'and b.number = 'number')
SELECT *
FROM tableA x
WHERE x.name = 'name'and x.number = 'number'

Related

How to avoid colliding column names when using a LEFT JOIN

I have table A, table B, and table C. Using a value from table A, I want to select things from table B and table C.
So I wrote this:
'SELECT * FROM a LEFT JOIN b ON a.w = b.x LEFT JOIN c ON a.y = c.z';
The problem is I have colliding column names in the three tables, and the last table column names overwrite the second one.
How can I fix this, I tried using the AS keyword but couldn't make it work, such as:
'SELECT * FROM a LEFT JOIN b AS bb ON a.w = bb.x LEFT JOIN c AS cc ON a.y = cc.z';
but it doesn't work. Maybe LEFT JOIN is not the best option? What I need to get is this:
a_id: u
a_name: v
b_id: w
b_name: x
c_id: y
c_name: z
As you can see, the array/object has a prefix for each table (table name + _) so there is no collision.
I'm hope I'm being clear, let me know if I'm not so I can edit the post. Thanks.
You need to provide aliases for each of the column names individually:
SELECT a.id AS a_id, a.name AS a_name,
b.id AS b_id, b.name AS b_name,
c.id AS c_id, c.name AS c_name
FROM a
LEFT JOIN b ON a.w = b.x
LEFT JOIN c ON a.y = c.z

Opposite of join in SQL with selecting 2 columns?

I have two tables A and B which I would like to select data where both table are common in a column (user_id) and are not similar in another column (A.columnX != B.columnY).
Actually, I would like the opposite of SQL joins.
Can anybody help me?
If you want to filter a join based on further logic, just use a WHERE clause:
SELECT
table_a.something,
table_a.something_else,
table_b.another_thing
FROM table_a
INNER JOIN table_b
ON table_b.user_id = table_a.user_id
WHERE
table_a.column_x != table_b.column_y;
You can provide the join query as:
select <<Column list>> from table1 a, table2 b where a.userid=b.userid and a.columnX!=b.columnY;
As you describe the question, you seem to want NOT EXISTS:
SELECT a.something, a.something_else,
b.another_thing
FROM table_a a INNER JOIN
table_b b
ON b.user_id = a.user_id
WHERE NOT EXISTS (SELECT 1
FROM table_b b2
WHERE b2.user_id = b.user_id and
b2.column_y = a.column_x
);
It is unclear if you want the user_id comparison in the correlation clause.

Multiple values from Joining three tables

I have to get A.Ref_id, B.Ref_id and B_Id's Ref_id
Table A_B having Column_A_ID and Column_B_ID
Table A having ID, Ref_id, Name, B_Id (This is the B.ID from table B)
Table B having ID, Ref_id, Name
Currently I'm having the following query
SELECT A.Ref_id as A_Ref_Id, B.Ref_id as B_Ref_Id, B_Id
FROM A_B
JOIN A on A_B.Column_A_ID = A.Id
JOIN B on A_B.Column_B_ID = B.Id
JOIN B AS Main_B on B.id = A.B_id;
By this query I'm getting the A.Ref_Id and B.Ref_Id columns correctly as they are showing their relevant Ref_id but for B_Id I want to have the Ref_id and it is showing the B.id instead.
You want this (right?): The value of B.Ref_id in the row where B.ID = A.B_Id while this row in turn must have A.ID=A_B.Column_A_ID. And the whole thing for every row in A_B:
SELECT A.Ref_id as A_Ref_id, B.Ref_id as B_Ref_id, Main_B.Ref_id
FROM A_B
JOIN A ON A_B.Column_A_ID = A.Id
JOIN B ON A_B.Column_B_ID = B.Id
JOIN B AS Main_B on Main_B.id = A.B_id;
(Last line of code with the important correction which was proposed by #Mojtaba)
So far, I see the ON condition of the last join has to use the alias name of table B:
SELECT A.Ref_id as A_Ref_Id, B.Ref_id as B_Ref_Id, B_Id
FROM A_B
JOIN A on A_B.Column_A_ID = A.Id
JOIN B on A_B.Column_B_ID = B.Id
JOIN B AS Main_B on Main_B.id = A.B_id;
By the way, having some example in sqlFiddle could be more helpful

How to use ELSE in SQL Query?

I have an SQL query to load items from my database.
$sql_query = "SELECT * FROM pagina_info
WHERE kwali='Luxuary' AND
id IN (
SELECT CASE WHEN kwali='Luxuary' THEN min(id)
ELSE max(id)
END
FROM pagina_info
GROUP BY product_name
)
AND voorraad>='1'
LIMIT ".$getal1.", ".$getal2."";
Now my question, is there a word that i can use in my ELSE state for taking the next value?
in my select i have THEN min(id) ELSE max(id), instead of max(id) i need a word or something for next value.
I can't find anything usefull hopefully anyone here can help me.
Bram
There is no key word to get the next id. But I am unsure if you mean the next id for that series of records, or the next id that will be assigned as an auto increment primary key.
Assuming the first you could use a user variable to add a sequence number, or you could join the table against itself where the 2nd copy has a larger id but matches on the product name.
Depending on your exact requirements (some table layouts and test data would help) then something like one of these would work.
Firstly, sub query being used with an IN clause
SELECT *
FROM pagina_info
WHERE kwali='Luxuary'
AND id IN
(
SELECT CASE
WHEN kwali='Luxuary' THEN min(a.id)
ELSE min(b.id)
END
FROM pagina_info a
LEFT OUTER JOIN pagina_info b
ON a.product_name = b.product_name
AND a.id < b.id
GROUP BY a.product_name
)
AND voorraad>='1'
LIMIT ".$getal1.", ".$getal2."";
Or doing a join against a sub query.
SELECT pagina_info.*
FROM pagina_info
INNER JOIN
(
SELECT CASE
WHEN kwali='Luxuary' THEN min(a.id)
ELSE min(b.id)
END AS id
FROM pagina_info a
LEFT OUTER JOIN pagina_info b
ON a.product_name = b.product_name
AND a.id < b.id
GROUP BY a.product_name
) c
ON pagina_info.id = c.id
WHERE pagina_info.kwali='Luxuary'
AND pagina_info.voorraad>='1'
LIMIT ".$getal1.", ".$getal2."";

Getting the maximum value from interrelated MySQL tables

I am trying to unify a pair of queries with a LEFT JOIN, so that I can perform an ORDER BY on a desired column.
Table A has an exclusive one-to-many relationship with Table B, and table B has an exclusive one-to-many relationship with Table C.
I want to get the maximum value of a column in Table C, for each row in Table A.
what I used to have was:
$tableA = SELECT * FROM tableA;
for each row in $tableA {
$maxValue = SELECT MAX(value) FROM tableC WHERE tableB_id IN (SELECT tableB_id FROM tableB WHERE tableA_id={$row['tableA_id']}) GROUP BY tableB_id;
}
and now I'm thinking along the lines of:
SELECT * FROM tableA LEFT JOIN (SELECT tableA_id, MAX(max_c_value) FROM (SELECT tableB_id, MAX(value) max_c_value FROM tableC GROUP BY tableB_id) t GROUP BY tableA_id) USING(tableA_id)
but I know that's gibberish. I am not sure where to go from here.
I'm finding it hard to explain the problem, sorry.
SELECT A.ID, MAX(C.MyField) as CField
FROM A
LEFT OUTER JOIN B
ON A.ID = B.A_ID
LEFT OUTER JOIN C
ON B.ID = C.B_ID
GROUP BY A.ID
You will get null value for CField if there is no rows corresponding.
select max(table3.field),table1.field from table1
join table2 on table1.id=table2.table1_id
join table3 on table2.id = table3.table2_id
group by table1.field
You were closer on the first try I think. You want something like this:
SELECT MAX(tableC.cValue) FROM tableA
LEFT JOIN tableB
ON tableA.tableA_id = tableB.tableA_id
LEFT JOIN tableC
ON tableB.tableB_id = tableC.tableB_id
http://www.w3schools.com/sql/sql_join.asp
I have managed to solve it on my own, only to come back here and find I was making things far too complicated for myself, getting lost in a sea of tables!
This code did actually work, but I have already replaced it with the simpler code suggested above:
SELECT * FROM A LEFT JOIN (
SELECT A_ID, MAX(val) FROM (
SELECT * FROM B LEFT JOIN (
SELECT B_ID, MAX(val) val FROM C GROUP BY B_ID
) x USING(B_ID)
) y GROUP BY A_ID
) z USING(A_ID);

Categories