【问题标题】:Progress OpenEdge, ODBC, recordsets, joining, oh my进展 OpenEdge、ODBC、记录集、加入,哦,我的
【发布时间】:2014-03-05 22:41:21
【问题描述】:

在这里很沮丧。我不是数据库管理员,但可以解决。我正在针对我们只能查看访问的 Progress OpenEdge 数据库编写一些 ODBC 查询。最长的时间没有问题,直到最近他们改变了数据结构,谁知道为什么,他们将客户电话号码移动到自己的名为“联系人”的表中,而在他们进入“cif”之前,地址等仍然保留.

他们没有为每个客户创建一行并为每个电话号码创建字段,而是使用 0-4、号码/电子邮件和客户的代码。因此,如果客户有 4 个电话号码,则他们有 4 行不同的代码、联系人字段和客户姓名重复。

我正在尝试将“联系人”表与“cif”表连接起来,这样无论在“cif”中列出多少次,它都会返回“cif”中提到的每个客户,但包括所有关联的电话号码来自每一行的“联系人”。

表结构简化如下:

Table "contact"

code |   contact(#)  | customer
--------------------------------
  0  | (123)456-7890 | ABC Corp
  1  | (123)456-7891 | ABC Corp
  0  | (987)654-3210 | CBA Inc


Table "cif"

customer | b_in_low | b_in_high
----------------------------------
ABC Corp |  50.45   | 134.66
ABC Corp |  64.45   | 188.99
CBA Inc  |  12.56   | 890.33

我要返回的是“cif”中每一行的连接行,但包含“contact”中的所有数字,因此上表将返回:

rsRow1) ABC Corp, 0, (123)456-7890, 1, (123)456-7891, 50.45, 134.66

rsRow2) ABC 公司, 0, (123)456-7890, 1, (123)456-7891, 64.45, 188.99

rsRow3) CBA Inc, 0, (987)654-3210,,, 12.56, 890.00

我不想要的:

rsRow1) ABC Corp, 0, #, 50.45, 134.66

rsRow2) ABC Corp, 1, #, 50.45, 134.66

rsRow3) ABC Corp, 0, #, 64.45, 188.99

rsRow4) ABC Corp, 1, #, 64.45, 188.99

rsRow5) CBA Inc, 0, #, 12.56 | 890.00

有意义吗?我可以让它在“cif”表上由一个 rs 工作,并在每个重复区域期间,使用“cif.customer”作为 WHERE 过滤器对“联系人”执行另一个查询,但显然它非常慢并且可能会导致数以千计的查询。

我可以让它只从“cif”返回 1 行,但从“contact”只返回 1 个号码

我可以让它返回最多 5 个重复的“cif”行,每个行有 5 个不同的电话号码。

简而言之,如何在列出“联系人”中的所有 +-5 电话号码的同时有效地从“cif”中获取 1 行?

【问题讨论】:

  • 如果不在结果端编写一些代码以将行转换为列,我看不到一种方法。
  • 这就是我来到这里的原因 Tim :D 我最终使用 ajax 来拉入一个格式化页面以获取它自己的联系信息。至少目前是这样。可以很好地满足我们的需求,并且比将第二个记录集放入第一个记录集要快得多,即使它本质上是在做同样的事情。
  • 预期结果是否正确?与 ABC Corp 并列的 2 不应该是 1 吗?所以:ABC Corp, 0, (123)456-7890,1,(123)456-7891,50.45,134.66
  • 你是对的 Ronald...typo...2 行都应该是 1。更新了 OP

标签: mysql sql odbc progress-4gl openedge


【解决方案1】:

这个怎么样:

SELECT c.customer
     , ISNULL(c1.code,'')
     , ISNULL(c1.contact,'')
     , ISNULL(c2.code,'')
     , ISNULL(c2.contact,'')
     , ISNULL(c3.code,'')
     , ISNULL(c3.contact,'')
     , ISNULL(c4.code,'')
     , ISNULL(c4.contact,'')
     , ISNULL(c5.code,'')
     , ISNULL(c5.contact,'')
     , c.b_in_low
     , c.b_in_high
FROM CIF AS c
LEFT OUTER JOIN Contact AS c1
ON c1.customer = c.customer
AND c1.code = 0
LEFT OUTER JOIN Contact AS c2
ON c2.customer = c.customer
AND c2.code = 1
LEFT OUTER JOIN Contact AS c3
ON c3.customer = c.customer
AND c3.code = 1
LEFT OUTER JOIN Contact AS c4
ON c4.customer = c.customer
AND c4.code = 1
LEFT OUTER JOIN Contact AS c5
ON c5.customer = c.customer
AND c5.code = 1

这取决于返回的“代码”字段的类型,如果您希望它为空白,您可能需要进行另一次翻译。

不漂亮,但我认为它有效。

【讨论】:

    【解决方案2】:

    SQL Server 中有一个 XML 选项,可让您获取多个结果并将它们合并为单个字段中的串联字符串。这是 STUFF FOR XML PATH 命令。这是我如何使用它的示例。

    SELECT call_number,  item_number,
        REPLACE(REPLACE(STUFF((SELECT DISTINCT ',','''' 
            + CONVERT(VARCHAR(20), item_line) + '**‘ 
            + item_number + '**‘ + work_code + ''''
            FROM stage_call_item_detail s
            WHERE h.source_system_code = s.source_system_code
            AND h.domain_code = s.domain_code
            AND h.call_number = s.call_number
            AND s.site_code IS NOT NULL
            ORDER BY 2
            FOR XML PATH(''))
        ,1, 1, '‘)  ,'<item_number>',''''),'</item_number>','''') call_line_item_list, *
    FROM stage_ssm_call_history h
    WHERE call_number = 'A1014-01'
    

    【讨论】:

      【解决方案3】:

      构建查询时可以使用缓冲区吗?

      如果可以的话,你可以这样做:

      为联系人定义缓冲区contactA ...contactN。

      FOR EACH cif WHERE cif.customer = "ABC Corp",
      FIRST contact OF cif OUTER-JOIN,
      FIRST contactA OF cif WHERE ROWID(contactA) <> ROWID(contact) OUTER-JOIN,
      ...
      FIRST contactN of cif
      WHERE ROWID(contactN) <> ROWID(contact) 
      AND ROWID(contactN) <> ROWID(contactA)
      ...
      

      这不是一个好的解决方案,而且性能可能会受到严重影响......而且这仅在您的联系人数量有限时才有效,例如 0-4。

      【讨论】:

      • 谢谢你。我最终做的并且很好地满足我们的需求的是做一个简单的查询并使用 ajax 为每个客户调用第二个查询。这并不理想,但它可以工作,并且只会将结果延迟几秒钟。对于我们对这份不运行但每天运行几次的报告的需求,这就足够了。这不是一个理想的解决方案,但在我找到一个更好、更有效的解决方案之前,这将解决问题。
      猜你喜欢
      • 1970-01-01
      • 2012-10-12
      • 2013-09-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 2018-02-14
      • 2014-09-06
      相关资源
      最近更新 更多