两个单独的查询;一个人需要计算另一个

时间:2017-08-10 17:42:23

标签: sql sql-server sql-server-2012 count

我有两个单独的查询。一个我用于详细信息文件,另一个我用于结束/预告片文件(我也有一个头文件,但那个与这个问题无关)。我将不得不将它们分开,因为它们将返回不同的列。

问题是我的详细文件有13470行但是当我在辅助查询(预告片文件)中进行计数时,我得到13,207行。原因是少数项目具有与主要项目ID关联的多个辅助ID。

如果我不使用SELECT DISTINCT,我可以获得相同的计数,但它会返回25,250行。我需要在我的详细信息文件中保留重复项。

详细信息查询很长,但只是理解即使ALMOST所有记录都是唯一的,但有些地方主要项目ID似乎只是重复,因为次要项目ID可能有几个不同的主要项目ID值

我已阅读以下文章,但似乎无法使其中任何一项工作。请注意,我使用的是Microsoft SQL Server 2012,而不是MySQL,但我确实将MySQL的概念应用于我的需求,其中一篇文章对此进行了解释:

Multiple COUNT() for multiple conditions in one query (MySQL)

SUM of grouped COUNT in SQL Query

Counting Values based on distinct values from another Column

所以,我想再根据我在详细信息文件中指定的所有条件(数十列和13,470行)进行计数。我的预告片文件只有两列一行。一个用于识别它是结束/预告片文件,另一个用于显示应该由详细信息文件返回的记录数。

这是我的“只是尝试看看它是否正常或是在正确的路径上”查询(并且没有):

    SELECT DISTINCT
    CAST('TRL' AS VARCHAR(3)) AS RECID,
    (CASE 
        WHEN COUNT(I2.VNDRITNM) > COUNT(DISTINCT I2.ITEMNMBR)
        THEN COUNT(I2.VNDRITNM)
        WHEN COUNT(I2.VNDRITNM) = COUNT(DISTINCT I2.ITEMNMBR)
        THEN COUNT(I2.ITEMNMBR)
        ELSE COUNT(DISTINCT I2.ITEMNMBR)
    END) AS TOTREC
    FROM Inv00101 I
    JOIN Inv00102 I2 ON I2.ITEMNMBR = I.ITEMNMBR
    JOIN ItemUnit I3 ON I3.ITEMNMBR = I.ITEMNMBR
    LEFT OUTER JOIN prodmaster D ON D.itemid = I.ITEMNMBR
    LEFT OUTER JOIN productinfo I4 ON I4.ITEMNMBR = I.ITEMNMBR
    WHERE (ITMDESC LIKE '%ART%' OR ITMDESC LIKE '%CRAFT%')

这会返回25,250行。

当然CASE声明是错误的,但我只是想探索它作为一种选择。有没有人知道如何让我的查询同步?

再次:

  • Microsoft SQL Server 2012
  • 1头文件(有效)
  • 1详细信息文件(作品)
  • 1个预告文件(未按预期工作)

使用CASE声明的预告片结果:

  | RECID | TOTREC |
--------------------
1 | TRL   | 25250  |

预告片结果只计算其中一列的DISTINCT

  | RECID | TOTREC |
--------------------
1 | TRL   | 13207  |

寻找:

  | RECID | TOTREC |
--------------------
1 | TRL   | 13470  |

任何建议都将不胜感激。谢谢!

修改

这是详细文件查询,但我删除了不相关的列;我执行了这个查询,它的工作原理与未编辑的查询相同,所以这应该足以说明:

SELECT DISTINCT
    RTRIM(CAST('DTL' AS VARCHAR(3))) AS RECID,
    RTRIM(CAST('12345' AS VARCHAR(10))) AS COMPANY,
    RTRIM(CAST(CASE 
                WHEN I2.VNDITNUM = ''
                THEN 'BLANK'
                ELSE I2.VNDITNUM END AS VARCHAR(20))) AS VNDITEM,
    RTRIM(CAST(I.ITEMNMBR AS VARCHAR(20))) AS NUMITEM,
    RTRIM(CAST(I.ITEMDESC AS VARCHAR(60))) AS ITMDESC,
    RTRIM(CAST(CASE 
          WHEN I.INACTIVE = '0' 
          THEN 'A' 
          WHEN I.INACTIVE = '1' 
          THEN 'I' END AS VARCHAR(1))) AS STATUS
FROM Inv00101 I
JOIN Inv00102 I2 ON I2.ITEMNMBR = I.ITEMNMBR
JOIN ItemUnit I3 ON I3.ITEMNMBR = I.ITEMNMBR
LEFT OUTER JOIN prodmaster D ON D.itemid = I.ITEMNMBR
LEFT OUTER JOIN productinfo I4 ON I4.ITEMNMBR = I.ITEMNMBR
WHERE (ITMDESC LIKE '%ART%' OR ITMDESC LIKE '%CRAFT%')

请注意,ITEMNMBR是主要的内部ID,而VNDITNUM是供应商/供应商ID,我将其称为辅助ID。 VNDITNUM有时会为产品的唯一主要内部ID提供多条记录。

正常结果如下:

  | RECID | COMPANY | VNDITEM | NUMITEM | ITMDESC | STATUS |
------------------------------------------------------------
1 | DTL   | 12345   | 011223  | 100234  | Game    | A      |
2 | DTL   | 12345   | 015992  | 104722  | Picture | A      |

但这里有一个例子,它可能会重复:

  | RECID | COMPANY | VNDITEM | NUMITEM | ITMDESC | STATUS |
------------------------------------------------------------
1 | DTL   | 12345   | 029445  | 109777  | Book A  | A      |
2 | DTL   | 12345   | 029478  | 109777  | Book A  | A      |

2 个答案:

答案 0 :(得分:1)

如果你的预告片是'查询只返回1条记录...然后你可以尝试使用tsql函数@@recordcount

像这样:

-- Declare an integer variable
DECLARE @rc as integer;

-- Your Detail query
SELECT
   IDont
   ,CareWhat
   ,TheDetailLogicIs
FROM
   Inv00101 as i
   JOIN WhoKnowsWhat as idk ON i.ITEMNMBR = idk.ITEMNMBR
WHERE 
   Who = Cares;

-- Assign your row count variable with the row count of the last executed query.
SET @rc = @@rowcount;

-- Your new Trailer query
SELECT
   'TRL' AS [RECID]
   ,@rc AS [TOTREC];

这样做的另一个好处是可以为您提供您感兴趣的实际查询的行数。另外,您不必执行重复的逻辑,这可能非常耗时(特别是如果您的详细信息查询与您实现的一样复杂)。

希望有所帮助:)

答案 1 :(得分:1)

我找到了一种使用派生表执行此操作的方法,以便我仍然可以将查询分开并使用SSIS填充单独的平面文件(无法使用具有多个select语句的查询执行此操作而不使用UNION S)。感谢所有帮助我到达那里!非常感谢您的建议。

以下是我使用的内容:

SELECT 
    CAST('TRL' AS VARCHAR(3)) AS RECID,
    COUNT(TotalRows) AS TOTREC 
FROM (SELECT DISTINCT
    RTRIM(CAST(CASE 
            WHEN I2.VNDITNUM = ''
            THEN 'BLANK'
            ELSE I2.VNDITNUM END AS VARCHAR(20))) AS VNDITEM,
    RTRIM(CAST(I.ITEMNMBR AS VARCHAR(20))) AS NUMITEM,
    @@ROWCOUNT AS TotalRows,
    I.ITMDESC
    FROM Inv00101 I
    JOIN Inv00102 I2 ON I2.ITEMNMBR = I.ITEMNMBR
    JOIN ItemUnit I3 ON I3.ITEMNMBR = I.ITEMNMBR
    LEFT OUTER JOIN prodmaster D ON D.itemid = I.ITEMNMBR
    LEFT OUTER JOIN productinfo I4 ON I4.ITEMNMBR = I.ITEMNMBR
    WHERE (ITMDESC LIKE '%ART%' OR ITMDESC LIKE '%CRAFT%')