错误:不使用EXISTS引入子查询时,选择列表中只能指定一个表达式

Posted

技术标签:

【中文标题】错误:不使用EXISTS引入子查询时,选择列表中只能指定一个表达式【英文标题】:Error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS 【发布时间】:2014-08-07 18:40:22 【问题描述】:

我有以下查询,它给我一个错误“当子查询没有与 EXISTS 一起引入时,只能在选择列表中指定一个表达式”。我无法弄清楚这在技术上有什么问题。

select clinicid,
       DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )) as YEAR,
       DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )) as MONTH,
       REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-') AS SalMonYY,
       (select rpTotal.clinicid,SUM(rpTotal.rpPackage) as rpPackage from 
        (
        select clinicid, count(1) as rpPackage
              from PackagePatients
              WHERE PackagePatients.clinicid = clinicid
              AND convert(date,patientdate) <  convert(date,saledate)
              group by clinicid
        union all
        select s.homeClinicId as clinicid,COUNT(1) as rpPackage
            from subscriptionHistory s 
            join patients p on s.ptientId = p.id 
            join products pl on s.productId = pl.id
            WHERE s.HomeClinicId = clinicid
            and pl.expDuration > 1
            group by s.homeClinicId) rpTotal group by rpTotal.clinicid) AS rpPackagesSold 
from PackagePatients

group by clinicid,
         DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )),
         DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )),
         REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-')

【问题讨论】:

您有一个子查询用作列,但子查询定义了多个列。您应该重写整个查询,而是加入子查询。 表达式(select rpTotal.clinicid,SUM(rpTotal.rpPackage) 有两列。它是在允许标量子查询的上下文中,但标量子查询最多只能从一行返回一列。 @SeanLange 但是我的子查询有一个联合子句,所以如果我加入子查询,我无法弄清楚如何解决这个问题 联合不是问题......好吧,除非该查询还返回超过 1 行。问题是您将子查询用作列,但它定义了两列。它怎么知道你想要哪一个? 【参考方案1】:

没有什么可做的,我认为您可以按照这些思路进行一些修改。这应该很接近。至少它会告诉你一种方法来完成这项工作。老实说,它可能需要完全重写。我没有表格之类的,但我确信完全不用子查询也可以做到这一点。

select clinicid,
       DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )) as YEAR,
       DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )) as MONTH,
       REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-') AS SalMonYY,
       rp.rpPackagesSold

from PackagePatients
join
(select SUM(rpTotal.rpPackage) as rpPackagesSold, clinicid
     from 
        (
        select clinicid, count(1) as rpPackage
              from PackagePatients
              WHERE PackagePatients.clinicid = clinicid
              AND convert(date,patientdate) <  convert(date,saledate)
              group by clinicid
        union all
        select s.homeClinicId as clinicid,COUNT(1) as rpPackage
            from subscriptionHistory s 
            join patients p on s.ptientId = p.id 
            join products pl on s.productId = pl.id
            WHERE s.HomeClinicId = clinicid
            and pl.expDuration > 1
            group by s.homeClinicId) rpTotal group by rpTotal.clinicid
) AS rp on rp.clinicid = PackagePatients.clinicid
group by clinicid,
         DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )),
         DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )),
         REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-')

【讨论】:

这看起来很有希望且合乎逻辑。但在代码的第一行出现“将表达式转换为数据类型 int 时算术溢出”错误。 除非您发布一些我可以编写代码的内容,否则我无法帮助您。 sqlfiddle 是开始这类事情的好地方。我的编码陷入了黑洞,没有任何信息进入。 @user3681350,pl.expDuration的数据类型是什么?【参考方案2】:

您需要将派生表移动到 from 子句,如下所示:

select clinicid,
       DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )) as YEAR,
       DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )) as MONTH,
       REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-') AS SalMonYY,
       SUM(rpPackagesSold.rpPackage) AS rpTotal

from PackagePatients
join 
(
        select clinicid, count(1) as rpPackage
              from PackagePatients
              WHERE PackagePatients.clinicid = clinicid
              AND convert(date,patientdate) <  convert(date,saledate)
              group by clinicid
        union all
        select s.homeClinicId as clinicid,COUNT(1) as rpPackage
            from subscriptionHistory s 
            join patients p on s.ptientId = p.id 
            join products pl on s.productId = pl.id
            WHERE s.HomeClinicId = clinicid
            and pl.expDuration > 1
            group by s.homeClinicId
) rpPackagesSold ON (rpPackagesSold.clinicid = PackagePatients.clinicid)


group by clinicid,
         DATEPART(YEAR,CONVERT(date,PackagePatients.SaleDate )),
         DATEPART(MONTH,CONVERT(date,PackagePatients.SaleDate )),
         REPLACE(RIGHT(CONVERT(VARCHAR(9),PackagePatients.SaleDate, 6), 6), ' ', '-')

【讨论】:

您应该使用 ANSI-92 样式的连接,而不是您在那里使用的旧 89 样式的连接。

以上是关于错误:不使用EXISTS引入子查询时,选择列表中只能指定一个表达式的主要内容,如果未能解决你的问题,请参考以下文章

不使用EXISTS引入子查询时,选择列表中只能指定一个表达式--sql中的错误

创建函数时出错 - 如果不使用 EXISTS 引入子查询,则选择列表中只能指定一个表达式

当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。 - SQL 服务器

当子查询没有引入 EXISTS 错误时,选择列表中只能指定一个表达式

我收到此错误:当未使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式

不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式