Wow, old question brought back to life...
Ok, I actually went through this a bit and here is the basics of it. In NPM proper there are two tables that you might be able to glean this info out of. The Interfaces table and the NodePortInterfaceMap, however both of these have their own problems in that Interfaces only has managed interfaces in it, and NodePortInterfaceMap has probably too complete info. ie: It will have a separate listing for each port/vlan combination, so if you have a switch that has 100 VLANs trunked on 1 port, you will get 100 listings for that port.
On the other hand, I got pretty good results out of NCM, which does an inventory of each device that is in NCM. The NCM.Interfaces table should then have a listing for every port on a switch, which is what you want. It's paring down the list a bit that gets difficult. There is a column called "PhysicalPort" which is misleading, it will list some Ethernet ports as not physical, not sure why that is. I had pretty good results, for switches at least, weeding out the ports with "virtual" in the type.
Came up with this query as a result, pretty basic but seems to work pretty well... Note that this is a SWQL query, not SQL... Can use this either in a report, or on a regular page by adding a resource of type "Custom Query"..
SELECT COUNT(InterfaceDescription) AS NumPorts, N.Caption
FROM NCM.Interfaces I JOIN Orion.Nodes N ON (I.Node.CoreNodeID = N.NodeID)
WHERE NOT (InterfaceTypeName like '%Virtual%')
GROUP BY N.NodeID, N.Caption
ORDER BY NumPorts DESC
HTH!