I am trying to implement a join so then I can order results of one table based on the column of another table. My SQL works perfectly when the records exists in both tables. The SQL also works when there are more records in table1 than there are in table2, providing I do not use the ORDER BY clause.
SQL:
SELECT * FROM table1
JOIN table2 b ON table1.col1 = b.col1
WHERE col3 != 0 ORDER BY b.col2 ASC;
Table 1
col1 | col2 | col3
__________________
1 foo 1
2 foo 1
5 foo 1
9 foo 0
10 foo 1
17 foo 0
14 foo 1
12 foo 1
Table 2
col1 | col2
___________
1 a
2 b
17 e
14 g
12 l
The part of the query ORDER BY b.col2 ASC is causing it to fail when the records between the two tables are not matching.
I cannot guarantee that a record will be present in both. Is there a way of still implementing this?
I am currently using mysqli but can use pdo if needed.
Like #Maximus2012 mentioned, try a LEFT JOIN. This will give you all of the records from table1 and any records from table2 which match col1 from table1.
SELECT * FROM table1
LEFT JOIN table2 b ON table1.col1 = b.col1
WHERE col3 != 0 ORDER BY b.col2 ASC
If you are looking for all records from table2 and any which match from table 1, use a RIGHT JOIN instead.
SELECT * FROM table1
RIGHT JOIN table2 b ON table1.col1 = b.col1
WHERE col3 != 0 ORDER BY b.col2 ASC
Making use of a LEFT JOIN to get this query:
SELECT table1.*,
table2.col2,
CASE WHEN table2.col2 IS NOT NULL THEN '0'
ELSE '1' END AS derived_column FROM table1
LEFT JOIN table2 ON table1.col1 = table2.col1
WHERE table1.col3 <> 0
ORDER BY derived_column, table2.col2
See if the above query works for your case. It is a bit complicated since the ORDER BY clause in the original query will put the non-matching columns before the matching ones in the result. To bypass this, I have conditionally created a derived column to return a value of 0 (for matching) and 1 (for non-matching). Then you order by this derived column first (rows with value 0 will come before those with value 1) and then order by table2.col2.
Related
I have two tables which contains duplicate values and unique values I don't need duplicate values from both the tables I need only unique values and copy it into a new table as output.
For ex:
Table 1 data
col1
101
102
103
104
Table 2 data
col1
101
102
103
105
Output required is
New Table 3 data
col1
104
105
The query is
SELECT
Table 1 data.col1
FROM
Table 1 data
LEFT JOIN
Table 2 data
ON
Table 1 data.col1 = Table 2 data.col1
WHERE
Table 2 data.col1 is NULL
Hope this will help :
(SELECT t1.col1 FROM t1 left join t2 on t1.col1 =t2.col1 WHERE t2.col1 is null) union (SELECT t2.col1 FROM t2 left join t1 on t1.col1=t2.col1 WHERE t1.col1 is null)
Use the Below Query with UNION:
(SELECT Table1.column1 FROM Table1 left join Table2 on Table1.column1 =Table2.column1 WHERE Table2.column1 is null)
union
(SELECT Table2.column1 FROM Table2 left join Table1 on Table1.column1=Table2.column1 WHERE Table1.column1 is null)
get the distinct value from both table (use UNION) to produce
101 102 103 104 105
then get the intersect data from both table (use INNER JOIN) to produce
101 102 103
after that, subtract result 2 from result 1 (in Oracle you can use MINUS operator, but you can use the same idea to build complex query for that in mysql using NOT IN operator)
Hope this will work. I tried in Oracle Database. hopefully It will work in MYSQL also.
SELECT col1
FROM tab1 outers
WHERE NOT EXISTS
(SELECT col1 FROM tab2 inners WHERE outers.COL1 = inners.COL1)
UNION
SELECT col1
FROM tab2 outers
WHERE NOT EXISTS
(SELECT col1 FROM tab1 inners WHERE outers.COL1 = inners.COL1);
INSERT INTO Table 3 data (clo1) SELECT CombinedValue FROM ( SELECT DISTINCT col1 AS CombinedValue FROM Table 1 data UNION ALL SELECT DISTINCT col1 FROM Table 2 data ) temp GROUP BY CombinedValue HAVING COUNT(*) =1
This query worked for me :)
Thank you all for your help
I have 2 tables as follows:
table1
ID Name Test
A011 John 1
A012 Lynda 1
A013 Micheal 1
A014 Jack 0
A021 Joe 1
A015 Paul 0
table2
ID Done
A011 1
A012 1
I want to select all rows from table1 that have an ID where the 3 first letters are equal to A01, and the test field is 1, and also the ID is not present in table2.
I tried this query:
SELECT a.* FROM table1 a LEFT JOIN table2 b ON a.ID = b.ID
WHERE a.test = 1 AND b.ID IS NULL
The result from that is 2 rows with ID A013 and A021. I tried to use LEFT(ID,3) to get the ID with A01, however, I couldn't achieve what I want.
How can I filter only the records where the ID starts with A01?
Try this, it will give you the desired result
SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.userid = t2.userid WHERE LEFT(t1.userid , 3) LIKE '%A01%' AND t1.userid NOT IN (SELECT userid from table2)
SELECT * FROM table1
WHERE test = 1
AND ID LIKE "AO1%"
AND ID NOT IN (SELECT ID from table2)
I have two tables, A & B
Table A Table B
order id order id quantity
----------- ------------ -------------
1 1 10
2 2 20
3 3 10
4 4 5
5 5 6
table A contains the order id and table B contains order id & quantity. I am trying
to run a MySQL query that shows rows with a total equal to or less than a number. For
example, a query to find rows equal to or less than 15 will show the rows with
order id's 4 & 5
Can you have multiple order_id and quantity pairs in table B? If so, I think what you want is this:
SELECT order_id FROM B GROUP BY order_id HAVING SUM(quantity) <= 15
If order_id is unique in table B. (does not have multiple rows with same id) then use the following:
SELECT a.order_id, col1, col2, col3
FROM TableA a
LEFT JOIN TableB b
ON a.order_id = b.order_id
WHERE b.quantity <= {$magic_number}
If order_id is not unique in table B(has multiple rows with the same order_id) then use the following:
SELECT a.order_id, col1, col2, col3
FROM TableA a
LEFT JOIN TableB b
ON a.order_id = b.order_id
GROUP BY a.order_id
HAVING SUM(b.quantity) <= {$magic_number}
I have a table members:
member_id, points
And I have another table bets:
member_id, finished
Consider following data for table members:
1 0
2 15000
3 0
And for bets:
1 -1
1 0
2 1
3 1
3 -1
In the table bets finished = -1 marks the bet as lost, 0 as unfinished and 1 as won.
How can I select member id's which have 0 points and all their bets are finished? With the data I have given, it should return one row with member id = 3.
You could use EXISTS clause:
select members.id
from members
where
points=0
and not exists (select null from bets where bets.id=members.id and status=0)
You can also use a LEFT JOIN:
select members.id
from
members left join bets
on members.id = bets.id
and bets.status=0
where
bets.id is null
and members.points=0
Use a JOIN, like so:
select members.member_id, members.points, bets.finished
from members
join bets on bets.member_id = members.member_id
where bets.finished <> 0 and members.points = 0;
You can use an inner join
SELECT member_id FROM members m
INNER JOIN bets b
ON m.member_id = b.member_id
WHERE b.finished = 0 AND m.points = 0
An inner join is the most common join operation used in applications and can be regarded as the default join-type. Inner join creates a new result table by combining column values of two tables (A and B) based upon the join-predicate. The query compares each row of A with each row of B to find all pairs of rows which satisfy the join-predicate. When the join-predicate is satisfied, column values for each matched pair of rows of A and B are combined into a result row.
http://en.wikipedia.org/wiki/Join_(SQL)#Inner_join
In your case, the join-predicate is m.member_id = b.member_id.
try this
SELECT m.member_id , b.finished FROM members m
INNER JOIN bets b
ON m.member_id = b.member_id
WHERE m.points = 0
and b.finished = 1
LOOK DEMO SQLFIDDLE
-- Most of the answers don't address your key issue - All of the bets are placed not just one of them
-- Here you go
Select memberid
from members
where points = 0
and member id not in (select member id from bets where bet <> -1 )
Or For Even Greater Efficiency as data grows to very very high volume
Select memberid
from members
where points = 0
and member id not in (select member id from bets where bet <> -1 and bets.memberid = members.memberid)
I have two mysql tables. One table with strings, for example abc, def, ghi, jkl. The other table contains info about the strings in the other table, for example 'Three first letters in the alphabet', '3-6 letters in the alphabet', and so on. There can be multiple (around 25 rows) for each string in this table.
I want to return 3 rows from the second table for each string in the first one, for example:
table1.string | table2.info
---------------------------
abc | blahblah
abc | blahblah2
def | blahblah
abc | blahblah3
def | blahblah2
def | blahblah3
I can get the strings from table1 first, the do a foreach and execute even more queries to get limit 3 from the table2. But that does not seem to be good for the performance.
How would a query like this look like?
I don't know whether it works in MySQL, but in MSSQL this would be
SELECT
table1.string,
table2.info
FROM table1 INNER JOIN table2 ON table2.stringID = table1.ID
WHERE ROW_NUMBER() OVER (PARTITION BY table1.string ORDER BY table2.info) <= 3
You can try this (it's not very fast though):
SELECT string,info FROM
(
select t1.string, t2.info,
#n_rec := IF(#tmp!=t1.string,1,#n_rec+1) as nrec,
#tmp := t1.string
FROM
table_1 t1
INNER JOIN table_2 t2 ON t2.table_1_id = t1.id
order by t1.string
)yy
INNER JOIN (SELECT #n_rec := 0) X
INNER JOIN (SELECT #tmp:= null)Y
WHERE nrec <=3;
You might want to use LEFT JOIN table_2 instead of INNER JOIN table_2 if you need to include records from table_1 with no info in table_2.