如何一对一地显示一对多关系

时间:2013-01-17 20:56:59

标签: sql database ms-access ms-access-2010

我正在使用寻呼系统。对于我的一些同事,我需要创建一个目录。目录中的每个人都有一个PAGER_ID和一个MESSAGING_ID。 PAGER_ID对于给定的寻呼设备是唯一的,而MESSAGING_ID对于人是唯一的。一个组可能轮班工作并将单个设备从一个班次传递到一个班次,导致几个人具有相同的PAGER_ID和不同的MESSAGING_ID。这很好,而且设计得很好。

对于我们的目录,用户希望满足以下条件:

  1. 每个PAGER_ID只显示一次(我知道我可以通过SELECT TOP 1到PAGER_ID执行此操作)
  2. 当PAGER_ID的MESSAGING_ID为十位数且一个或多个其他MESSAGING_ID位数不同时,首选10位MESSAGING_ID。
  3. 如果没有10位MESSAGING_ID,则会有一个MESSAGING_ID与任何其他位数相同。
  4. 简洁:他们只希望看到PAGER_ID / MESSAGING_ID的一条记录。如果每个人都列在目录中,他们就不在乎。只要每个PAGER_ID在目录中只显示一个MESSAGING_ID,并且只要10个数字的MESSAGING_ID优先于那些不是10个数字长的MESSAGING_ID,他们就不会真正关心MESSAGING_ID。

    我尝试过TOP和IIF查询的组合,并且无法让他们以所需的方式一起玩得很好。

    我的基本选择查询是:

    SELECT
        tbl_Amcom_Prod.NAME,
        tbl_Amcom_Prod.PAGER_ID,
        tbl_Amcom_Prod.MESSAGING_ID
    FROM tbl_Amcom_Prod
    WHERE
        (((tbl_Amcom_Prod.PAGER_ID) Like "241662"
        Or (tbl_Amcom_Prod.PAGER_ID) Like "18888"))
    ORDER BY tbl_Amcom_Prod.PAGER_ID;
    

    结果如下:

    |     NAME       | PAGER_ID | MESSAGING_ID |
    --------------------------------------------
    | TESTER 1       |    18888 | 18888        |
    --------------------------------------------
    | SMITH, MARK    |    18888 | 5735551262   |
    --------------------------------------------
    | SUPERVISOR     |   241662 | 102621       |
    --------------------------------------------
    | JOHN, JONES    |   241662 | 101436       |
    --------------------------------------------
    | SEEGER, ROBERT |   241662 | 101409       |
    --------------------------------------------
    

    他们想看到这个:

    |     NAME       | PAGER_ID | MESSAGING_ID |
    --------------------------------------------
    | SMITH, MARK    | 18888    | 5735551262   |
    --------------------------------------------
    | SUPERVISOR     | 241662   | 102621       |
    --------------------------------------------
    

    有什么想法吗?

3 个答案:

答案 0 :(得分:1)

也许:

SELECT tt.NAME, tt.PAGER_ID, tt.MESSAGING_ID
FROM tt
WHERE tt.PAGER_ID In (
    SELECT [PAGER_ID] 
    FROM tt a 
    WHERE  a.MESSAGING_ID IN (
        SELECT TOP 1 MESSAGING_ID 
        FROM tt 
        ORDER BY Len(MESSAGING_ID) DESC,PAGER_ID))

你的桌子在哪里。

答案 1 :(得分:1)

好吧,假设您的桌子是MyTable,那么您只需要分组:

SELECT FIRST(Name), PAGER_ID,  MAX(MESSAGING_ID)
FROM MyTable
GROUP BY PAGER_ID

答案 2 :(得分:1)

如果PAGER_IDMESSAGING_ID都是文本数据类型,则此查询会返回您请求的结果。

SELECT
    t.NAME,
    t.PAGER_ID,
    t.MESSAGING_ID
FROM
    (
        SELECT
            sub1.PAGER_ID,
            DLookUp(
                "MESSAGING_ID",
                "tbl_Amcom_Prod",
                "PAGER_ID = '" & sub1.PAGER_ID &
                    "' AND Len(MESSAGING_ID) = " &
                    sub1.MESSAGING_ID_max_length
            ) AS MESSAGING_ID
        FROM
            (
                SELECT
                    PAGER_ID,
                    Max(Len(MESSAGING_ID))
                        AS MESSAGING_ID_max_length
                FROM tbl_Amcom_Prod
                GROUP BY PAGER_ID
            ) AS sub1
    ) AS sub2
    INNER JOIN tbl_Amcom_Prod AS t
    ON sub2.MESSAGING_ID = t.MESSAGING_ID
WHERE t.PAGER_ID In ("241662","18888")
ORDER BY t.PAGER_ID;

如果PAGER_ID是Long Integer而不是text,请使用...

            DLookUp(
                "MESSAGING_ID",
                "tbl_Amcom_Prod",
                "PAGER_ID = " & sub1.PAGER_ID &
                    " AND Len(MESSAGING_ID) = " &
                    sub1.MESSAGING_ID_max_length
            ) AS MESSAGING_ID

和......

WHERE t.PAGER_ID In (241662,18888)

如果MESSAGING_ID为长整数而不是文字,请将Max(Len(MESSAGING_ID))更改为Max(Len(CStr(MESSAGING_ID))),将Len(MESSAGING_ID)更改为Len(Cstr(MESSAGING_ID))

相关问题