创建一个SQL查询,使用多个表中的变量执行数学运算

时间:2011-02-16 13:57:55

标签: sql tsql sql-server-2008

这是我迄今为止尝试过的一个例子:

表格的样子:

广告

ID  |  lowrange  |  highrange
-------------------------------
1   |  15        |  20
2   |  21        |  30

审核(此连接中未在此查询中使用)

MissingOrVoid

ID  |  Item  |  Missing  |  Void
---------------------------------
1   |  17    |   1       |  0
1   |  19    |   1       |  0

我尝试使用的最新查询:

SELECT    I.*,
          SUM(
              (I.HIGHRANGE - I.LOWRANGE + 1)
              - (Count(M.Missing) from M where M.ID = I.ID)
              - (Count(M.Void) from M where M.ID = I.ID)) AS Item_Quantity


FROM Inventory I 
    JOIN Audit A 
        ON A.ID = I.ID 
    JOIN MissingOrVoid M 
        ON M.ID = I.ID

结果应为:

ID  |  lowrange  |  highrange  |  Item_Quantity
-----------------------------------------------
1   |  15        |  20         |  4
2   |  21        |  30         |  10

我无法准确记住我在哪里进行了更改,但在之前的尝试中,之前收到的错误消息是“无法对包含聚合或子查询的表达式执行聚合函数”。目前错误是“from”附近的错误语法(M.Missing旁边的错误,但在我对SQL的最低限度知识中,似乎这些语法问题导致彻底失败,并且可能存在查询的潜在问题,直到所有语法问题都已修复。)

我真正轰炸的部分显然是SUM()部分。我远离数据库架构师,所以有人可以解释如何正确执行此操作并可能指向资源方向以了解此类函数吗?

由于

6 个答案:

答案 0 :(得分:2)

你几乎把它弄好了。我猜测缺失/无效是BIT类型,你不能直接SUM。

SELECT I.*,
    (I.HIGHRANGE - I.LOWRANGE + 1)
    - (select Count(nullif(M.Missing,0)) from MissingOrVoid M where M.ID = I.ID)
    - (select Count(nullif(M.Void,0)) from MissingOrVoid M where M.ID = I.ID)
    AS Item_Quantity
FROM Inventory I 

如果某个项目不能同时丢失和无效,那么

SELECT I.*,
       I.HIGHRANGE - I.LOWRANGE + 1
           - (select Count(case when M.Missing=1 or M.Void=1 then 1 end)
              from MissingOrVoid M where M.ID = I.ID)
           AS Item_Quantity
FROM Inventory I

事实上,如果它只在MissingOrVoid中缺失或无效时出现,那么上述查询中的CASE将始终为真,因此这简化为

SELECT I.*,
       I.HIGHRANGE - I.LOWRANGE + 1
           - (select Count(*) from MissingOrVoid M where M.ID = I.ID)
           AS Item_Quantity
FROM Inventory I

答案 1 :(得分:0)

最初,我有一个问题是你是否需要对这些值求和。如果您的库存表每个项目有一行,那么这不是必需的。我会假设您的表可以为给定项目提供多行,然后从那里开始。

我认为问题只是构造子查询的问题。我没有对此进行过测试,但我认为它看起来应该更像:

select I.ID, 
    I.Item, 
    SUM(I.HighRange - I.LowRange + 1)
    - (
        select SUM(M.Missing + M.Void)
        from dbo.Audit A
        where A.ID = I.ID
      )
from Inventory I
group by I.ID, I.Item

答案 2 :(得分:0)

这是你想要做的吗?我不确定缺失和无效列中的数字是什么,除非它们只是标志......

SELECT    I.*,
          ((I.highrange - I.lowrange + 1)
              - SUM(M.Missing)
              - SUM(M.Void)) AS Item_Quantity


FROM Inventory I 
    JOIN MissingOrVoid M 
        ON M.ID = I.ID

答案 3 :(得分:0)

以下查询有效。这假设每个id只有一个高范围和低范围。

CREATE TABLE #Inventory (ID INT,Lowrange INT,highrange INT)
CREATE TABLE #MissingOrVoid (Id INT,item INT, missing INT, void INT)

INSERT #Inventory
        ( ID, Lowrange, highrange )
VALUES  ( 1, -- ID - int
          15, -- Lowrange - int
          20  -- highrange - int
          )
INSERT #Inventory
        ( ID, Lowrange, highrange )
VALUES  ( 2, -- ID - int
          21, -- Lowrange - int
          30  -- highrange - int
          )
INSERT #MissingOrVoid
        ( Id, item, missing, void )
VALUES  ( 1, -- Id - int
          17, -- item - int
          1, -- missing - int
          0  -- void - int
          )
INSERT #MissingOrVoid
        ( Id, item, missing, void )
VALUES  ( 1, -- Id - int
          19, -- item - int
          1, -- missing - int
          0  -- void - int
          )


SELECT #Inventory.ID,
       #Inventory.highrange,
       #Inventory.Lowrange,
       highrange-Lowrange+1
           -SUM(ISNULL(missing,0))
           -SUM(ISNULL(void,0)) AS ITEM_QUANTITY
FROM #Inventory
left JOIN  #MissingOrVoid ON #Inventory.ID = #MissingOrVoid.Id
GROUP BY #Inventory.ID,#Inventory.highrange,#Inventory.Lowrange


DROP TABLE #Inventory
DROP TABLE #MissingOrVoid

答案 4 :(得分:0)

我会说这会奏效:

SELECT  I.ID,I.Lowrange as Lowrange,
        I.highrange as Highrange,
        Highrange-Lowrange+1-COUNT(J.missing)-COUNT(J.void) AS ITEM_QUANTITY 
FROM Inventory I
left JOIN  ( select missing as missing, void as void, id from MissingOrVoid 
            ) J
    ON I.ID = J.Id
JOIN Audit A 
    ON A.ID = I.ID          
GROUP BY I.ID,Highrange,Lowrange

但它看起来像RemoteSojourner所说的很多(而且他的那个也更美观)。

答案 5 :(得分:0)

我将提供派生表方法,因为它可能比相关子查询(逐行运行)更快

SELECT I.*,        
I.HIGHRANGE - I.LOWRANGE + 1 -  MissingVoidCount AS Item_Quantity 
FROM Inventory I  
JOIN 
    (SELECT ID,Count(*) AS MissingVoidCount FROM MissingOrVoid GROUP BY ID) M
        on M.ID = I.ID

当然在现实生活中,我绝不会使用select *。您也可以使用CTE方法。

    ;WITH  MissingVoid(ID, MissingVoidCount) AS
    (
        SELECT ID, Count(*)  FROM MissingOrVoid GROUP BY ID
    )
    SELECT 
        I.*,        
        I.HIGHRANGE - I.LOWRANGE + 1 -  MissingVoidCount AS Item_Quantity 
    FROM Inventory I
    JOIN MissingVoid M
        on M.ID = I.ID