Below is the replicas of the tables I have created. My goal is to simply pick the unique id_num from the First Table which is not found on the Second Table.
I have tried doing the code below but somehow, I kept getting empty results
SELECT `first_table`.name FROM `first_table`
INNER JOIN `second_table`
ON `first_table`.id_num = `second_table`.id_num
WHERE `first_table`.name = `second_table`.name
First Table:
id_num | name
301 | Bobby
123 | George
25 | Vicky
Second Table:
id_num | name
301 | Bobby
435 | George
25 | Vicky
My desire result I am looking for:
id_num | name
435 | George
LEFT JOIN should work here.
SELECT `first_table`.name FROM `first_table`
LEFT JOIN `second_table`
ON `first_table`.id_num = `second_table`.id_num
WHERE `second_table`.id_num is NULL
See also this useful infographic
try this using NOT IN
select `id_num` , name from `table2` where name not in (
SELECT t1.name FROM `table1` t1
INNER JOIN `table2` t2
ON t1.id_num = t2.id_num )
DEMO HERE
Related
I have two arrays like this,
First Table (infos):
------------------------------
| ID | User1 | User2 | User3 |
------------------------------
| 1 | 20 | 30 | 12 |
------------------------------
Second Table (Users):
---------------------
| ID | Name | Email |
---------------------
| 12 | Test | Test# |
---------------------
| 20 | Bla | Test# |
---------------------
| 30 | Bate | Test# |
---------------------
I want to get the information of users on one row from the IDs on the first table.
I try by getting The row from the first table and fetching on users, but I want to optimize the function with just one Query.
SELECT * FROM infos;
SELECT * FROM Infos i,Users u WHERE u.ID = u.User1 (or 2 ...)
Is there any solution ?
You could use joining the table users 3 times, one for each userid you want show the related name (or other values):
select a.id
, a.user1
, b.Name as user1name
, a.user2
, c.name as user2name
, a.user3
, d.name as user3name
from infos a
inner join Users b on a.user1 = b.id
inner join Users c on a.user1 = c.id
inner join Users d on a.user1 = d.id
And just as suggested, you should not use old implicit join syntax based on comma-separated table names and where clause, you should use (since 1992) explicit joins. This syntax performs the same query, but is more clear.
This is a design error. Use a N:N relation (an additional table) to allow any number of users for the first table. With the relation, other queries will be easier.
A relation table looks like this:
create table relation
(
table1_id int unsigned not NULL,
table2_id int unsigned not NULL,
primary key(table1_id,table2_id)
);
A typical query (and I dislike a.* generally):
select a.*, b.*
from table1 a, table2 b, relation r
where r.table1_id = a.id
&& r.table2_id = b.id
Hi, guys
Can't find answer in other topics, so asking here.
I have a Table in database
Table
------------------------------
id | name | last_name | created_by_id |
1 | Bilbo ..| Baggins.....| 0 .................... |
2 | Frodo . | Baggins.....| 1 ................... |
Is there any way i can get 1st row name value by using 2nd row created_by_id ?
I need to get sentence Frodo Baggins was created by Bilbo Baggins.
Can't find the right sql sentence
You need self join :
select t.*, t1.name, t1.last_name
from table t inner join
table t1
on t1.id = t.created_by_id
where t.id = 2;
you can just use a join
select *,<your string stuff here>
from <table> as a
inner join <table> as b
on a.id = b.created_by_id
company_name | macid | expiry_date
---------------------------------------------
abc | 123456789012 | 2017-03-23
qwe | 987654321012 | 2018-05-24
asd | 456789123012 | 2019-07-07
abc | 789456123000 | 2017-03-23
abc | 445544444444 | 2018-03-03
abc | 555555555555 | 2017-03-25
company_name | desktop | server
abc 123456789012 555555555555
789456123000
I have above two table and I want all macid and expiry date which is present in table1 and table2. Also I have store all macid as new line and desktop macid and server macid in different columns. My query
"select a.macid,a.expity_date from table1 a,table2 b where a.macid like b.desktop or a.macid like %'b.server%'"
but is show result null. Please help to solved.
I want result
macid | expiry_date
---------------------------------------------
123456789012 | 2017-03-23
789456123000 | 2017-03-23
555555555555 | 2017-03-25
for table2 if I want to search mac_id them I have to use
"select * from table2 where desktop like '%123456789012%'"
I can not retrieve record without %(percentage)
I think it is just a typo, not expity_date, it's expiry_date in your query, see demo.
select a.macid, a.expiry_date
from table1 a, table2 b
where a.macid like b.desktop or a.macid like b.server
However, it is more better to use join not a comma(,) to do join things:
select a.macid, a.expiry_date
from table1 a
join table2 b
on a.macid like b.desktop or a.macid like b.server
also check demo here.
Another thing is if desktop and server is as same as macid, just use equal(=) is fine as well.
You have to make two separate JOIN and then UINON the results.
SELECT macid, expiry_date
FROM table1 JOIN table2
ON table1.macid = table2.desktop
UNION
SELECT macid, expiry_date
FROM table1 JOIN table2
ON table1.macid = table2.server
Here is the working demo: http://sqlfiddle.com/#!9/dccea43/1
Try this:
"select a.macid,a.expity_date from table1 a JOIN table2 b ON (a.macid like b.desktop OR a.macid like b.server)"
I'm using the following query to select data from 3 different tables. tbl_invoices and tbl_clients have unique records. Each tbl_invoices record has multiple tbl_invoice_entries records:
$query = 'SELECT T1.*, T2.*, T3.*
FROM tbl_invoices T1
LEFT JOIN tbl_invoice_entries T2
ON T1.number = T2.invoice_number
LEFT JOIN tbl_clients T3
ON T1.client = T3.client_id
WHERE date_format(date, '%Y') = ".$_POST['year']." AND date_format(date, '%c') = ".$_POST['month']." ORDER BY date, number ASC'
$stmt = $conn->prepare($query)
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
This currently returns all records in tbl_invoice_entries. How do I change my query in order to only return the first tbl_invoice_entries record for each tbl_invoices record.
Here are the tables:
tbl_clients
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
| 1 | John | Doe |
| 2 | Jane | Doe |
+----+-----------+----------+
tbl_invoices
+----+--------+--------+------------+
| id | number | client | date |
+----+--------+--------+------------+
| 1 | 14 | 1 | 2015-07-14 |
| 1 | 15 | 2 | 2015-07-14 |
+----+--------+--------+------------+
tbl_invoice_entries
+----+----------------+------------+
| id | invoice_number | produkt |
+----+----------------+------------+
| 1 | 14 | Fish |
| 2 | 14 | Bread |
| 3 | 15 | Vegetables |
| 4 | 15 | Fruit |
+----+----------------+------------+
So the results I'm looking for are:
John Doe 14 Fish 2015-07-14
Jane Doe 15 Vegetables 2015-07-14
Thanks for any help!
By linking the invoice_entries table not directly through the invoice number but by the id of its first entry you can achieve what you want:
SELECT firstname,lastname,number,product,date
FROM tbl_invoices T1
LEFT JOIN tbl_invoice_entries T2
ON T2.id =(select min(id) from tbl_invoice_entries
where invoice_number=number)
LEFT JOIN tbl_clients T3
ON T1.client = T3.id
WHERE ...
You need to tell the RDBMS what you intend by the first row. There is no natural order in tuples. If you want the tuple with lowest ID given the same invoice_number, then it would require another query
SELECT tbl1.* FROM tbl_invoice_entries AS tbl1
JOIN ( SELECT MIN(id) AS id, invoice_number FROM tbl_invoice_entries
GROUP BY invoice_number ) AS tbl2
USING (id);
The above query is equivalent to tbl_invoice_entries but only has the lowest ID of each invoice number. You can do it as a VIEW (actually two, since you can't use subqueries in a VIEW):
CREATE VIEW tbl_invoice_entries_firstnumber AS
SELECT MIN(id) AS id, invoice_number
FROM tbl_invoice_entries
GROUP BY invoice_number;
CREATE VIEW tbl_invoice_entries_first AS
SELECT tbl1.* FROM tbl_invoice_entries AS tbl1
JOIN tbl_invoice_entries_firstnumber
USING (id);
After that you can use tbl_invoice_entries_first instead of tbl_invoice_entries in your current query.
Keep in mind that the view is dynamic, so it is only a shorthand for a more complex query. This means that your current query will become more complicated and require a longer time:
SELECT T1.*, T2.*, T3.*
FROM tbl_invoices AS T1
LEFT JOIN tbl_invoice_entries_first AS T2
ON T1.number = T2.invoice_number
LEFT JOIN tbl_clients AS T3
ON T1.client = T3.id; -- you have no client_id in T3
I have set up a fiddle here.
Or you can modify your query more, and add a JOIN condition on T2 so that it only fetches, again, the minimum ID - or whatever ordering condition you prefer:
SELECT T1.*, T2.*, T3.*
FROM tbl_invoices AS T1
LEFT JOIN tbl_invoice_entries AS T2
ON (
-- (( T1.number = T2.invoice_number AND )) --
T2.id = (
SELECT MIN(id) FROM tbl_invoice_entries
WHERE invoice_number = number
))
LEFT JOIN tbl_clients AS T3
ON T1.client = T3.id;
UPDATE: The check on number was commented out (see also #cars10's solution) because it is carried over by the inner subquery.
Finally you can do this in code, i.e. you save the value of the previous tuple and order the query as needed; then discard all unneeded tuples. If you have few entries per invoice, this might be worthwhile:
// pseudo code
if (prev.client == tuple.client)
and
(prev.invoice == tuple.invoice)
continue;
prev = tuple;
-- use tuple.
I'm having difficulty figuring out how to create the proper syntax for my query.
Here is what i'm pulling. I have 2 tables.
Table 1 : Fields (user_id, name)
Table 2 : Fields (user_id, type, are_code, phone_number).
Table 1 can only have 1 record per user_id.
1 | John Doe
Table 2 can have up to 3 records per user_id:
1 | Home | 123 | 456.4567
1 | Work | 000 | 987.1467
1 | Mobi | 098 | 987.1756
How can i select everything so that my table will result in 1 record pulled like so :
user_id | name | home# | work# | mobi#
I tried this, which duplicates and doubles rows based on amount of entries within Table 2.
SELECT a.user_id,
b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id
That unfortunately returned 3 rows which is not good :(.
1 | John Doe | area | home# |
1 | John Doe | area | work# |
1 | John Doe | area | mobi# |
Any help and or pointers would be greatly appreciated.
Try this out:
SELECT
u.user_id,
u.name,
MAX(CASE WHEN p.type = 'Home' THEN phone_number END) HomeNumber,
MAX(CASE WHEN p.type = 'Work' THEN phone_number END) WorkNumber,
MAX(CASE WHEN p.type = 'Mobi' THEN phone_number END) MobiNumber
FROM phones p
JOIN users u ON p.user_id = u.user_id
GROUP BY u.user_id, u.name
Output:
| USER_ID | NAME | HOMENUMBER | WORKNUMBER | MOBINUMBER |
|---------|----------|------------|------------|------------|
| 1 | John Doe | 456.4567 | 987.1467 | 987.1756 |
Fiddle here.
Also note that you can remove u.name if u.user_id determines u.name... which is most likely the case as it seems to be a primary key. That would speed things up a little bit.
Note: This assumes that you cant have more than one same type for the same user (as it is in your example data, which only has one column for home, work and mobile.
Use user_contact_phones.type to get exact what you want, like-
SELECT a.user_id,
b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id where b.type='Home'
Here's a solution that will work:
select u.user_id, u.name,
thome.area_code as home_area_code, thome.phone_number as home_phone_number,
twork.area_code as work_area_code, twork.phone_number as work_phone_number,
tmobi.area_code as mobi_area_code, tmobi.phone_number as mobi_phone_number
from table1 u
left outer join table2 thome on u.user_id = thome.user_id and thome.type = 'Home'
left outer join table2 twork on u.user_id = twork.user_id and twork.type = 'Work'
left outer join table2 tmobi on u.user_id = tmobi.user_id and tmobi.type = 'Mobi'
Please note the use of left outer join instead of inner join in case the record for a particular type does not exist. You will get null values for those columns in your result set with left outer join. With inner join, you would not get a result for a user that did not have all three types. Good luck!