SQL在子查询中选择

时间:2015-05-20 15:08:04

标签: sql-server select subquery select-case

您好我的查询如下,并在其中包含一个子查询:

ALTER PROCEDURE [dbo].[POBalance] @PONumber NVARCHAR(50) 
AS
BEGIN
    SELECT CASE 
            WHEN X.STATUS = 'False'
                THEN (  SELECT A.Description
                            ,C.qty AS POqty
                            ,B.Qty AS PDQty
                            ,CASE 
                                WHEN A.partialflag = 'false'
                                    THEN '0'
                                ELSE A.qty
                                END AS Balance
                            ,A.Unit
                            ,A.Unitprice
                            ,A.Partialflag
                        FROM tblPOdetails AS A
                        INNER JOIN tblPDdetails AS B ON A.id = B.id
                        INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                        WHERE A.PONo = @PONumber
                        )
            ELSE (  SELECT A.Description
                        ,C.qty AS POqty
                        ,B.Qty AS PDQty
                        ,C.qty AS Balance
                        ,A.Unit
                        ,A.Unitprice
                        ,A.Partialflag
                    FROM tblPOdetails AS A
                    INNER JOIN tblPDdetails AS B ON A.id = B.id
                    INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                    WHERE A.PONo = @PONumber)
            END
    FROM tblPOHeader AS X
    WHERE x.PONo = @PONumber
END

我得到的错误是:

当子查询不是时,只能在选择列表中指定一个表达式 与EXISTS一起介绍。

我的查询有什么问题..我的子查询似乎没问题。

提前谢谢

4 个答案:

答案 0 :(得分:2)

你不能选择表格以便clausule。你可以这样做(我没有测试过):

    SELECT A.Description
                                ,C.qty AS POqty
                                ,B.Qty AS PDQty
                                ,CASE 
                                    WHEN A.partialflag = 'false'
                                        THEN '0'
                                    ELSE A.qty
                                    END AS Balance
                                ,A.Unit
                                ,A.Unitprice
                                ,A.Partialflag
                            FROM tblPOdetails AS A
                            INNER JOIN tblPDdetails AS B ON A.id = B.id
                            INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                            INNER JOIN tblPOHeader X ON x.PONo = A.PONo
                            WHERE A.PONo = @PONumber and X.STATUS = 'False'

    UNION ALL

    SELECT A.Description
                            ,C.qty AS POqty
                            ,B.Qty AS PDQty
                            ,C.qty AS Balance
                            ,A.Unit
                            ,A.Unitprice
                            ,A.Partialflag
                            FROM tblPOdetails AS A
                            INNER JOIN tblPDdetails AS B ON A.id = B.id
                            INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                            INNER JOIN tblPOHeader X ON x.PONo = A.PONo
                            WHERE A.PONo = @PONumber and X.STATUS <> 'False'

但我觉得X.STATUS有点 - 如果是的话你应该这样做:

    SELECT A.Description
                                ,C.qty AS POqty
                                ,B.Qty AS PDQty
                                ,CASE 
                                    WHEN A.partialflag = 'false'
                                        THEN '0'
                                    ELSE A.qty
                                    END AS Balance
                                ,A.Unit
                                ,A.Unitprice
                                ,A.Partialflag
                            FROM tblPOdetails AS A
                            INNER JOIN tblPDdetails AS B ON A.id = B.id
                            INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                            INNER JOIN tblPOHeader X ON x.PONo = A.PONo
                            WHERE A.PONo = @PONumber and X.STATUS = 0

    UNION ALL

    SELECT A.Description
                            ,C.qty AS POqty
                            ,B.Qty AS PDQty
                            ,C.qty AS Balance
                            ,A.Unit
                            ,A.Unitprice
                            ,A.Partialflag
                            FROM tblPOdetails AS A
                            INNER JOIN tblPDdetails AS B ON A.id = B.id
                            INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                            INNER JOIN tblPOHeader X ON x.PONo = A.PONo
                            WHERE A.PONo = @PONumber and X.STATUS <> 0

答案 1 :(得分:1)

你真的在寻找这个吗?

ALTER PROCEDURE [dbo].[POBalance] @PONumber NVARCHAR(50)
AS
BEGIN
    DECLARE @Status NVARCHAR(MAX)

    SELECT @Status = X.STATUS
    FROM tblPOHeader AS X WHEREx.PONo = @PONumber

    IF @Status = 'False'
    BEGIN
        SELECT A.Description
            ,C.qty AS POqty
            ,B.Qty AS PDQty
            ,CASE 
                WHEN A.partialflag = 'false'
                    THEN '0'
                ELSE A.qty
                END AS Balance
            ,A.Unit
            ,A.Unitprice
            ,A.Partialflag
        FROM tblPOdetails AS A
        INNER JOIN tblPDdetails AS B ON A.id = B.id
        INNER JOIN tblpodetailshistory AS C ON A.id = C.id
        WHERE A.PONo = @PONumber
    END
    ELSE
    BEGIN
        SELECT A.Description
            ,C.qty AS POqty
            ,B.Qty AS PDQty
            ,C.qty AS Balance
            ,A.Unit
            ,A.Unitprice
            ,A.Partialflag
        FROM tblPOdetails AS A
        INNER JOIN tblPDdetails AS B ON A.id = B.id
        INNER JOIN tblpodetailshistory AS C ON A.id = C.id
        WHERE A.PONo = @PONumber
    END
END

此代码将存储然后检查@Status的值,并根据值是否为False,然后它将返回其中一个查询的结果集。

答案 2 :(得分:0)

您无法为一个表达式选择多个字段。您的别名会使其更加明显。您可以选择多个值并仅提供一个别名! 请参考此

Only One Expression in case

And this one too

Another one here

答案 3 :(得分:0)

select * from tblPOHeader where PONo = @PONumber

只返回一行,你可以做那样的事情

    declare @STATUS nvarchar(200) = ( select STATUS from tblPOHeader where PONo = @PONumber)
    if @STATUS = 'False'
    SELECT A.Description
                            ,C.qty AS POqty
                            ,B.Qty AS PDQty
                            ,CASE 
                                WHEN A.partialflag = 'false'
                                    THEN '0'
                                ELSE A.qty
                                END AS Balance
                            ,A.Unit
                            ,A.Unitprice
                            ,A.Partialflag
                        FROM tblPOdetails AS A
                        INNER JOIN tblPDdetails AS B ON A.id = B.id
                        INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                        WHERE A.PONo = @PONumber 

    ELSE
        SELECT A.Description
                        ,C.qty AS POqty
                        ,B.Qty AS PDQty
                        ,C.qty AS Balance
                        ,A.Unit
                        ,A.Unitprice
                        ,A.Partialflag
                        FROM tblPOdetails AS A
                        INNER JOIN tblPDdetails AS B ON A.id = B.id
                        INNER JOIN tblpodetailshistory AS C ON A.id = C.id
                        WHERE A.PONo = @PONumber