Sybase *= 到 Ansi Standard,同一个内表有 2 个不同的外表

Posted

技术标签:

【中文标题】Sybase *= 到 Ansi Standard,同一个内表有 2 个不同的外表【英文标题】:Sybase *= to Ansi Standard with 2 different outer tables for same inner table 【发布时间】:2012-08-24 13:43:28 【问题描述】:

我正在尝试迁移一些遗留程序代码。我无法找出 ANSI 标准语法来产生相同的结果。

以下是我尝试过的众多组合之一。第二个连接的内表是什么,是第一个连接的输出还是源表。

请帮助我有很多代码要更改。

原始 SQL 语句

select * from  
JT1 a, JT2 b, JT3 c  
where a.ID *= b.ID   
  and c.JOB *= b.JOB  

我的转化

select *   
from JT1 a  
 left outer join JT2 b   
 on a.ID = b.ID  
 right outer join JT3 c  
 on c.JOB = b.JOB  

以下是 SQL 表定义和示例数据。

Create table JT1 (  
 ID   int(4)   not null,  
 NAME char(20) not null)  


Create table JT2 ( 
  ID  int(4)   not null, 
  JOB char(20) not null)  


Create table JT3 ( 
  JOB  char(20) not null, 
  DUTY char(20) not null)  

INSERT INTO dbo.JT1 VALUES(10, "Saunders")  
INSERT INTO dbo.JT1 VALUES(20, "Pernal")  
INSERT INTO dbo.JT1 VALUES(30, "Marenghi")  
INSERT INTO dbo.JT2 VALUES(20, "Sales")  
INSERT INTO dbo.JT2 VALUES(30, "Clerk")   
INSERT INTO dbo.JT2 VALUES(30, "Mgr")  
INSERT INTO dbo.JT2 VALUES(40, "Sales")  
INSERT INTO dbo.JT2 VALUES(50, "Mgr")  
INSERT INTO dbo.JT3 VALUES("Mgr","Evaluate")  
INSERT INTO dbo.JT3 VALUES("Mgr","Reports")  
INSERT INTO dbo.JT3 VALUES("Mgr","Meeting")  
INSERT INTO dbo.JT3 VALUES("Clerk","Stocking")  
INSERT INTO dbo.JT3 VALUES("Clerk","Customer Request")  

【问题讨论】:

感谢您通过提供创建要查询的数据所需的内容,让我能够轻松地尝试制定解决方案。 【参考方案1】:

如何创建查询...

示例表:交易

输入日期 PartyIdno 类别 贷记/借记金额 ------ ---------- ---------- --------- ------------ --- ----- 1 02-01-2016 1 收据 C 8,200 1 02-01-2016 5 付款 D 8,200 2 14-02-2016 1 销售额 D 11,200 2 14-02-2016 4 销售额 C 6,500 2 14-02-2016 2 销售额 C 4,700 输出 ------ 输入日期 PartyIdno 借方 贷方 余额 ----- ------ ---------- ------ -------- ----------- SubId 子金额 ----- --------- 1 02-01-2016 1 8,200 8,200 铬 02-01-2016 5 8,200 博士 2 14-02-2016 1 11,200 3,000 博士 14-02-2016 4 6,500 铬 14-02-2016 2 4,700 铬

SQL 语句:

GLOBALSSS.Open_DB_Connection() Dim cmd As New Sql Command("Select T1.ENTRY,COALESCE(T1.PARTYIDNO,T2.PARTYIDNO) AS Color FROM TRANSACT T1 FULL OUTER JOIN (SELECT PARTYIDNO FROM TRANSACT WHERE ENTRY=1) T2 ON 1 = 0 WHERE T1.PARTYIDNO =1 或 T2.PARTYIDNO-1 ",连接) Dim da 作为新的 SqlDataAdapter(cmd) 将 dt 调暗为新数据表 da.填充(dt) DataGridView1.DataSource = dt GLOBALSSS.Close_DB_Connection()

【讨论】:

【参考方案2】:

好吧,我花了一段时间,但试试这个:

select   a.ID,  a.NAME, b.ID,   b.JOB,  a.JOB,  a.DUTY    
from (Select * from #jt1    
      cross join #jt3  ) a 
left outer join #jt2 b    
  on a.ID = b.ID    and a.job = b.job

多次使用左连接运算符的问题在于,你确实有一个隐藏的交叉连接。这应该会得到正确的结果,至于结果是否一直不正确是由于开发人员不了解他们在做什么,只有您自己知道。

【讨论】:

对我来说看起来是正确的。我在兼容级别为 80 的 SQL Server 数据库中创建了这些表,这就是它给出的执行计划。 我在一个旧的 sql server db 中执行此操作,该数据库仍然设置为我自己的兼容性 80。这就是为什么那些旧的隐含连接非常糟糕的原因,你真的不;了解他们在做什么。他必须更改的一些代码可能多年来一直返回不正确的结果。这就是为什么 SQL Server 文档说这些隐含连接可能会返回不正确的结果,因为有时它们会作为交叉连接进行交互。我很高兴 OP 正在解决这个问题,但对其他人来说,如果您使用过这种语法,则需要替换它,因为它不明确,并且服务器可能没有按照您的想法做。 感谢 HLGEM,该解决方案有效。我们将不得不解决结果的正确性,因为我倾向于同意它们可能不正确。我一直在努力寻找解决方案的原因之一。【参考方案3】:

*= 等价于left [outer] join

=* 等价于right [outer] join

【讨论】:

【参考方案4】:

原始查询等价于:

select * 
from JT1 a
left join JT2 b on a.ID = b.ID
left join JT3 c on c.JOB = b.JOB

【讨论】:

以上是关于Sybase *= 到 Ansi Standard,同一个内表有 2 个不同的外表的主要内容,如果未能解决你的问题,请参考以下文章

sql MS SQL ANSI-Standard与非ANSI内部联接

C, ANSI C, embedded c, IKM online assessment

什么是SQL

SQL基础总结——20150730

如何将 Sybase 应用程序迁移到 Web?

make file 和 GCC标志学习