Sql 根据另一列的最大值选择多个列

Sql 根据另一列的最大值选择多个列,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我有Oracle 11g数据库和以下三个表(简化): IP表,包含IP标识符、IP和IP状态以及FQDN。IPs可能会重复 +-------+-------------+-----------+-----------+ | ID_IP | IP | IP_STATUS | FQDN | +-------+-------------+-----------+-----------+ | 1 | 192.168.1.1 | 1 | test.com

我有Oracle 11g数据库和以下三个表(简化):

IP表,包含IP标识符、IP和IP状态以及FQDN。IPs可能会重复

+-------+-------------+-----------+-----------+
| ID_IP |     IP      | IP_STATUS |   FQDN    |
+-------+-------------+-----------+-----------+
|     1 | 192.168.1.1 |         1 | test.com  |
|     2 | 192.168.1.1 |         2 | test.com  |
|     3 | 192.168.1.1 |         3 | test.com  |
|     4 | 10.10.45.12 |         2 | test2.com |
+-------+-------------+-----------+-----------+
VLAN表,包含和VLAN标识符以及VLAN编号

+---------+-------------+
| VLAN_ID | VLAN_NUMBER |
+---------+-------------+
|       1 |           3 |
|       2 |           5 |
|       3 |           7 |
+---------+-------------+
关联VLAN和IP的表:

+-------+---------+
| IP_ID | VLAN_ID |
+-------+---------+
|     1 |       1 |
|     2 |       2 |
|     3 |       3 |
|     4 |       2 |
+-------+---------+
在实际的IP表中,主键是元组(IP,IP_状态)。我的目标是创建一个新表来消除IP_状态,为此,我希望聚合IP并获取VLAN_编号更高的IP的ID_IP和FQDN。SELECT查询的答案如下:

+-------+-------------+-----------+
| ID_IP |     IP      |   FQDN    |
+-------+-------------+-----------+
|     3 | 192.168.1.1 | test.com  |
|     4 | 10.10.45.12 | test2.com |
+-------+-------------+-----------+
我可以使用以下查询获取IP:

SELECT i.IP, max(v.VLAN_ID)
FROM IPS i 
LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP=v_i.ID_IP
LEFT JOIN VLANS v ON v_i.ID_VLAN=v.ID_INSTANCIA
GROUP BY i.IP;
我不知道的是如何获取其他列。我尝试使用如下子查询:

SELECT i.ID_IP, i.IP, i.FQDN 
FROM IPS i
WHERE i.IP IN (
    SELECT i.IP, max(v.VLAN_ID)
    FROM IPS i 
    LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP=v_i.ID_IP
    LEFT JOIN VLANS v ON v_i.ID_VLAN=v.ID_INSTANCIA
    GROUP BY i.IP;
)
但它不起作用,因为子查询返回两个值,我需要max(vlan.vlan_ID)来进行聚合

我怎样才能获得正确的IP_ID


谢谢大家!

您可能需要尝试使用子句。大概

WITH IPWITHMAXVLANID(IP, MAXVLAN) AS (
  SELECT i.IP, max(v.VLAN_ID)
   FROM IPS i 
   LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP=v_i.ID_IP
   LEFT JOIN VLANS v ON v_i.ID_VLAN=v.ID_INSTANCIA
   GROUP BY i.IP
)
SELECT i.ID_IP, i.IP, i.FQDN, iml.MAXVLAN
FROM IPS i
INNER JOIN IPWITHMAXVLANID iml on i.IP = imp.IP

希望这有帮助。

您可能需要尝试使用子句。大概

WITH IPWITHMAXVLANID(IP, MAXVLAN) AS (
  SELECT i.IP, max(v.VLAN_ID)
   FROM IPS i 
   LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP=v_i.ID_IP
   LEFT JOIN VLANS v ON v_i.ID_VLAN=v.ID_INSTANCIA
   GROUP BY i.IP
)
SELECT i.ID_IP, i.IP, i.FQDN, iml.MAXVLAN
FROM IPS i
INNER JOIN IPWITHMAXVLANID iml on i.IP = imp.IP

希望这有帮助。

您可以使用分析子句按
IP
拆分,并按
VLAN\u编号
排序,然后筛选以仅保留每组中的第一行:

SELECT ID_IP, IP, FQDN
FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY i.IP ORDER BY v.VLAN_NUMBER DESC) AS NB,
     i.ID_IP, i.IP, i.FQDN
    FROM IPS i 
    LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP = v_i.ID_IP
    LEFT JOIN VLANS v ON v_i.VLAN_ID = v.VLAN_ID
) t_a
WHERE NB = 1

您可以使用分析子句按
IP
拆分,并按
VLAN\u编号
排序,然后筛选以仅保留每个组中的第一行:

SELECT ID_IP, IP, FQDN
FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY i.IP ORDER BY v.VLAN_NUMBER DESC) AS NB,
     i.ID_IP, i.IP, i.FQDN
    FROM IPS i 
    LEFT JOIN VLAN_IP_REL v_i ON i.ID_IP = v_i.ID_IP
    LEFT JOIN VLANS v ON v_i.VLAN_ID = v.VLAN_ID
) t_a
WHERE NB = 1