【问题标题】:How to implement joins inside sub-query referring tables in main query in SQL 2008如何在 SQL 2008 中的主查询中实现子查询引用表内的联接
【发布时间】:2011-08-10 04:56:44
【问题描述】:

我有一个以下查询,它在子查询中有连接,连接表是从主查询 from 子句中引用的。这是 SQL Server 2000 语法,我正在尝试将其迁移到 2008 语法,但在运行时出现错误。请提出建议。

CREATE TABLE [dbo].[PRODUCT]
(
        [pid] [int] NULL,
        [NAME] [nchar](10) NULL,
        [PDID] [int] NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[PRODUCTDESC]
(
        [PDID] [int] NULL,
        [DESC] [nchar](10) NULL
) ON [PRIMARY]

--Test Data
insert into PRODUCT values (1,'ONE',1);
insert into PRODUCT values (2,'2',2);
insert into PRODUCT values (3,'3',2);
insert into PRODUCT values (4,'4',null);
insert into PRODUCT values (5,'4',5);

INSERT INTO PRODUCTDESC VALUES (1,'ONENEN');
INSERT INTO PRODUCTDESC VALUES (2,'TWEONEN');

-- SQL Server 2000
SELECT 
    Name,
    (SELECT [DESC]
     FROM PRODUCTDESC
     WHERE PRODUCT.PDID *= PRODUCTDESC.PDID)
FROM   
    PRODUCT 

--RESULTS
/*
    Name    (No column name)
    ONE         ONENEN    
    2           TWEONEN   
    3           TWEONEN   
    4           NULL
    */

-- SQL Server 2008
SELECT 
    NAME,
    (SELECT [DESC]
     FROM PRODUCT
     LEFT OUTER JOIN PRODUCTDESC ON PRODUCT.PDID = PRODUCTDESC.PDID)
FROM   
    PRODUCT 

--RESULTS
/*
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
*/

在上面的 2008 年查询中,在子查询中我们如何访问主查询表单子句中引用的 TABLES,这样我就不会得到子查询返回超过 1 个值的错误

请提出建议。

【问题讨论】:

  • sqlnewbie:您无权简单地删除其他所有人帖子的内容,请停止建议这种性质的编辑。我再次回滚你的问题,所以它包含了这里每个人都回答的内容。
  • @wesley - 我又回滚了
  • sqlnewbie,编辑用于澄清、拼写、语法、标点符号、格式等 - 我不确定你的想法,但我认为没有人会感谢你删除答案他们花时间为您提供。
  • @Wesley - 被拒绝。我还标记了 mod 注意。
  • @sqlnewbie:如果您的问题需要澄清,请澄清。但不要只是删除问题文本;那是行不通的。如果您有新问题,请使用“提问”按钮提问。

标签: sql-server tsql sql-server-2008 join sql-server-2000


【解决方案1】:
SELECT PRODUCT.NAME
       ,PRODUCTDESC.[DESC]
FROM   PRODUCT
LEFT JOIN PRODUCTDESC
    ON PRODUCT.PDID = PRODUCTDESC.PDID

请注意,问题在于您有一个标量子查询,它必须只返回一行(或无行)。请注意,这意味着使用该数据的原始查询在 SQL Server 2000 中也会失败。此外,在 SQL Server 2000 和 SQL Server 2008R2 以及其间的所有版本中,左连接 *= 运算符甚至都不是必需的:

DECLARE @PRODUCT TABLE (
    [PDID] [int] NULL,
    [NAME] [nchar](10) NULL
)

DECLARE @PRODUCTDESC TABLE (
    [PDID] [int] NULL,
    [DESC] [nchar](10) NULL
)

--Test Data
insert into @PRODUCT values (1,'ONE');
insert into @PRODUCT values (2,'2');
insert into @PRODUCT values (3,'3');
insert into @PRODUCT values (4,'4');

INSERT INTO @PRODUCTDESC VALUES (1,'ONENEN');
INSERT INTO @PRODUCTDESC VALUES (2,'TWEONEN');


--SQL 2000-2008R2
SELECT Name,
       (SELECT [DESC]
        FROM   @PRODUCTDESC AS PRODUCTDESC
        WHERE  PRODUCT.PDID = PRODUCTDESC.PDID)
FROM   @PRODUCT AS PRODUCT

【讨论】:

  • 谢谢,是的,这会为我获取结果,但我正在寻找一种替代方法,了解如何在 select 子句中定义的子查询的连接中访问外部查询表
  • @Srinivas - 您的错误是因为子查询不能用作标量。您可以在子查询中使用外部值。在您的情况下,因为您使用了 PRODUCT 两次,所以您需要为外部的别名,以便它不会被内部的隐藏。我相信您的第一个查询在 SQL Server 2000 中会因同样的问题而失败,因为子查询在用作标量时只需要返回一行。
  • 我已经在 SQL 2000 兼容模式下尝试了原始查询,它正确地获取了结果集...
  • @Cade——我在想的是在 SQL 2000 查询中,子查询使用来自外部查询的结果,并将该结果集与子查询中定义的表应用连接。 ...我想知道我们如何在 2008 年推出此功能
  • 即使在 SQL Server 2000 中,您也不应该在任何情况下使用隐式左连接。它甚至在 SQL Server 2000 中也被破坏,并且不能保证返回正确的结果。对于 2008 年,您需要立即使用它替换所有代码。这是已弃用的代码,它不会在 SQl Server 的下一版本中完全可用。解决这个问题应该是一项关键任务。
【解决方案2】:

这是你想做的吗?

select p.Name,pdesc.DESC, from PRODUCT p inner join PRODUCTDESC pdesc on pdesc.PDID=p.PDID

【讨论】:

  • 谢谢,是的,这会为我获取结果,但我正在寻找一种替代方法,了解如何在 select 子句中定义的子查询的连接中访问外部查询表。
【解决方案3】:

您的子查询中不需要外连接。这样就可以了。

SELECT Name,
       (SELECT [DESC]
        FROM   PRODUCTDESC
        WHERE  PRODUCT.PDID = PRODUCTDESC.PDID)
FROM   PRODUCT

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 2012-12-12
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2011-04-14
    相关资源
    最近更新 更多