【问题标题】:Oracle - Comparing multiple recordsOracle - 比较多条记录
【发布时间】:2018-11-18 14:27:00
【问题描述】:

我现在陷入了一个奇怪的场景。

我有一张有很多记录的表。其中一些看起来像:

表 1

----------------------------------------------
M_ID                ROLE_ID
----------------------------------------------
idA                 adVA12^~^dsa25
idA                 adsf32^~^123^~^asdf32
idA                 hdghf45
idB                 fdngfhlo43^~^
idB                 pnsdfmg23
idC                 123ghaskfdnk
idC                 hafg32^~^^~^gasdfg
----------------------------------------------

表2

-----------------------------------------------------------
ROLE_ID                     ADDR1       ADDR2       ADDR3
-----------------------------------------------------------
adVA12^~^dsa25              18          ben         street
adsf32^~^123^~^asdf32       24          naruto      park
hdghf45                     18          ben         street
fdngfhlo43^~^               40          spartan     ave
pnsdfmg23                   40          spartan     ave
123ghaskfdnk                14          southpark   ave
hafg32^~^^~^gasdfg          88          brooks      st
-----------------------------------------------------------

我有这些表由ROLE_ID 链接。

我的要求是,Table 1 中单个M_ID 的所有ROLE_IDs 必须针对它们在Table 2 中的地址字段进行比较。如果单个M_ID对应的所有ROLE_ID的地址在Table 2中都不相同,则应返回。

也就是说,在这种情况下,我的结果应该是:

-----------------------------
M_ID    ROLE_ID
-----------------------------
idA     adVA12^~^dsa25
idA     adsf32^~^123^~^asdf32
idA     hdghf45
-----------------------------

M_ID,以及对应的ROLE_IDs。

我不知道如何比较多条记录。

【问题讨论】:

    标签: sql select oracle11g


    【解决方案1】:

    略有不同的方法:

    SELECT t1.m_id, substr(sys.stragg(',' || t1.role_id),2) Roles, 
    t2.ADDR1, t2.ADDR2, t2.ADDR3
    FROM   t1
    JOIN   t2 ON t1.role_id = t2.role_id
    GROUP BY t1.m_id, t2.ADDR1, t2.ADDR2, t2.ADDR3;
    
    
    
    "M_ID"    "ROLES"             "ADDR1"   "ADDR2" "ADDR3"
    "A"       "A1,A2,A3,A5,A6,A7"   "1"       "2"     "3"
    "A"       "A4"                  "4"       "2"     "3"
    

    您可以添加 HAVING COUNT(0) > 1 来获取所有匹配项,或者使用 HAVING COUNT(0) = 1 来获取仅使用一次的所有实例,或者使用它而不使用 HAVING 来获取摘要。

    我使用了以下测试数据:

    CREATE TABLE TEST_ROLE (
        ID INTEGER PRIMARY KEY,
        M_ID VARCHAR2(32) NOT NULL,
        ROLE_ID VARCHAR2(256) NOT NULL
    );
    
    CREATE TABLE TEST_ROLE_ADDRESS (
        ROLE_ID VARCHAR2(256) NOT NULL,
        ADDR1 VARCHAR2(1000),
        ADDR2 VARCHAR2(1000),
        ADDR3 VARCHAR2(1000)
    );
    
    INSERT INTO TEST_ROLE VALUES(1, 'A', 'A1');
    INSERT INTO TEST_ROLE VALUES(2, 'A', 'A2');
    INSERT INTO TEST_ROLE VALUES(3, 'A', 'A3');
    INSERT INTO TEST_ROLE VALUES(4, 'A', 'A4');
    INSERT INTO TEST_ROLE VALUES(5, 'A', 'A5');
    INSERT INTO TEST_ROLE VALUES(6, 'A', 'A6');
    INSERT INTO TEST_ROLE VALUES(7, 'A', 'A7');
    
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A1', '1', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A2', '1', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A3', '1', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A4', '4', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A5', '1', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A6', '1', '2', '3');
    INSERT INTO TEST_ROLE_ADDRESS VALUES ('A7', '1', '2', '3');
    

    【讨论】:

    • 谢谢你 zythis :)
    【解决方案2】:

    我会加入表格并计算不同的地址数量:

    SELECT m_id, role_id
    FROM   (SELECT t1.m_id AS m_id,
                   t1.role_id AS role_id,
                   COUNT(DISTINCT t2.addr1 || '-' || t2.addr2 || '-' || t2.addr3)
                        OVER (PARTITION BY t1.m_id) AS cnt
            FROM   t1
            JOIN   t2 ON t1.role_id = t2.role_id) t
    WHERE  cnt > 1
    

    【讨论】:

    • 这太棒了!谢谢穆雷尼克!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多