Reputation: 3205
I need to extract some data from a postgresql database, taking a few elements from each of two tobles. The tables contain data relating to physical network devices, where one table is exclusively for mac addresses of these devices. Each device is identified by location (vehicle) and function (dev_name).
table1 (assets):
vehicle
dev_name
dev_serial
dev_model
table2: (macs)
vehicle
dev_name
mac
interface
What i tried:
SELECT assets.vehicle, assets.dev_name, dev_model, dev_serial, mac
FROM assets, macs
AND interface = 'E0'
ORDER BY vehicle, dev_name
;
But it seems to not be matching vehicle and dev_name as i thought it would. Instead it seems to print every combination of mac and dev_serial, which is not the intended output, as i want one line for each.
How would one make sure that it matches the mac address to the device based on assets.dev_name = macs.dev_name and assets.vehicle = macs.vehicle?
Note: Some devices in assets
may not have a recorded mac address in mac
, in which case i want them displayed anyway with an empty mac
Upvotes: 0
Views: 154
Reputation: 354
A simple join keyword is the solution of your problems
SELECT assets.vehicle, assets.dev_name, dev_model, dev_serial, mac
FROM assets A join macs M
ON A.dev_name = M.dev_name
Otherwise going on with your approach, just modify the query as follows:
SELECT assets.vehicle, assets.dev_name, dev_model, dev_serial, mac
FROM assets, macs
WHERE interface = 'E0' AND assets.dev_name = macs.dev_name
ORDER BY vehicle, dev_name;
remember that for any join the condition is very important, other wise it just becomes another cross join, i.e. combination of each row with every other row.
Upvotes: 0
Reputation: 117380
Read about SQL join.
select
a.vehicle, a.dev_name, a.dev_model, a.dev_serial, m.mac
from assets as a
inner join macs as m on m.dev_name = a.dev_name and m.vehicle = a.dev_name
where m.interface = 'E0'
order by a.vehicle, a.dev_name
In your case it's inner join, but if you want to get all assets and show mac for those with interface E0, you could use left outer join:
select
a.vehicle, a.dev_name, a.dev_model, a.dev_serial, m.mac
from assets as a
left outer join macs as m on
m.dev_name = a.dev_name and m.vehicle = a.dev_name and m.interface = 'E0'
order by a.vehicle, a.dev_name
Upvotes: 0
Reputation: 204766
When using a join
you can specify which columns have to match
SELECT a.vehicle, a.dev_name, dev_model, dev_serial, mac
FROM assets a
LEFT JOIN macs m ON m.vehicle = a.vehicle
AND m.dev_name = a.dev_name
WHERE interface = 'E0'
ORDER BY a.vehicle, a.dev_name
Upvotes: 3