尝试根据select中子查询的值过滤行

时间:2019-01-10 16:02:49

标签: sql sql-server

我将以说我是SQL的初学者来作为开头...

我正在尝试生成一份清单,该清单在报表运行日期之前的一年内尚未从订单中扣除。也许我会采用错误的方式,但是我通过在选择嵌套的子查询中使用求和函数来获取已向订单收取的零件数量。


    SELECT b.binid AS 'Bin Location',
        i.partnumber AS 'Part No.',
        i.descrip AS 'Description',
        i.mfgcode AS 'Mfg Code',
        i.stocked AS 'Stocked',
        i.itemtype AS 'Part Type',
        i.onhand AS 'On Hand',
        (
            SELECT COALESCE(SUM(l.qtyreqd),0)
            FROM orderln l
            LEFT OUTER JOIN orders o
                ON l.orderid = o.orderid
            WHERE l.itemid = i.itemid
                AND o.ordertype = 'REPAIR'
                AND NOT o.STATUS = 'CANCELED'
                AND l.linetype = 'PART'
                AND l.chgdate BETWEEN '1/10/2018 12:00:00 AM'
                    AND '1/11/2019 12:00:00 AM'
            ) AS 'Usage'
    FROM item i
    LEFT OUTER JOIN iteminv b
        ON b.itemid = i.itemid
    WHERE i.shopid = 'FD TRACTOR'
        AND b.binid BETWEEN '00.01.00'
            AND '00.20.00'
        AND 'Usage' < 1
    ORDER BY b.binid ASC,
        i.partnumber ASC;

我希望看到这样的列表:

+---------------+-----------+---------------+-----------+-----------+-----------+-----------+---------+ 
|Bin Location   |Part No.   |Description    |Mfg Code   |Stocked    |Part Type  |On Hand    |Usage    |
+---------------+-----------+---------------+-----------+-----------+-----------+-----------+---------+
|00.01.00       |0002       |Widget 2       |XXXXX      |Y          |STANDARD   |5.000000   |0.000000 |
|00.02.00       |0003       |Widget 3       |XXXXX      |Y          |STANDARD   |0.000000   |0.000000 |
+-----------------------------------------------------------------------------------------------------+

但是我没有得到任何结果。如果我在WHERE子句中删除了“ AND'Usage'<1”位,则会得到适用的结果,但我不希望任何使用值等于或大于1的情况。

2 个答案:

答案 0 :(得分:0)

这是您的问题:

SELECT 
    (/*... some expressions*/) AS 'Usage'
FROM 
    --....
WHERE 
    --....
    AND 'Usage' < 1

您正在使用子查询来生成列,并将其别名为Usage。过滤此Usage列的方式有两个问题:

  • 您正在编写显式文字值'Usage',这不是正确引用正在生成的列的方法。表达式'Usage' < 1应该引发转换失败错误,因为引擎将尝试将文字值“ Usage”转换为整数以进行比较。
  • 您不能在同一范围的WHERE子句中引用别名。您必须重复生成列的相同表达式,或者将结果集包装在子查询/ CTE上并在外部引用。

    ;WITH CTE AS
    (
        SELECT 
            (/*... some expressions*/) AS 'Usage'
        FROM 
            --....
    )
    SELECT
        --....
    FROM
        CTE AS C
    WHERE 
        --....
        AND C.Usage < 1 -- No single quotes!
    

答案 1 :(得分:0)

您的查询应引发转换错误,因为您正在尝试将varchar与int类型进行比较。

无论如何,您都应该在where子句中包含子查询,如下所示:

SELECT b.binid AS 'Bin Location',
    i.partnumber AS 'Part No.',
    i.descrip AS 'Description',
    i.mfgcode AS 'Mfg Code',
    i.stocked AS 'Stocked',
    i.itemtype AS 'Part Type',
    i.onhand AS 'On Hand',
    (
        SELECT COALESCE(SUM(l.qtyreqd),0)
        FROM orderln l
        LEFT OUTER JOIN orders o
            ON l.orderid = o.orderid
        WHERE l.itemid = i.itemid
            AND o.ordertype = 'REPAIR'
            AND NOT o.STATUS = 'CANCELED'
            AND l.linetype = 'PART'
            AND l.chgdate BETWEEN '1/10/2018 12:00:00 AM'
                AND '1/11/2019 12:00:00 AM'
        ) AS 'Usage'
FROM item i
LEFT OUTER JOIN iteminv b
    ON b.itemid = i.itemid
WHERE i.shopid = 'FD TRACTOR'
    AND b.binid BETWEEN '00.01.00'
        AND '00.20.00'
    AND 
    (
        SELECT COALESCE(SUM(l.qtyreqd),0)
        FROM orderln l
        LEFT OUTER JOIN orders o
            ON l.orderid = o.orderid
        WHERE l.itemid = i.itemid
            AND o.ordertype = 'REPAIR'
            AND NOT o.STATUS = 'CANCELED'
            AND l.linetype = 'PART'
            AND l.chgdate BETWEEN '1/10/2018 12:00:00 AM'
                AND '1/11/2019 12:00:00 AM'
        ) < 1
ORDER BY b.binid ASC,
    i.partnumber ASC;

或者您也可以使用像EzLo建议的cte,使查询更易于阅读和理解。