【发布时间】:2018-01-19 02:10:21
【问题描述】:
我有两个单独的查询。一个用于详细信息文件,另一个用于结尾/拖车文件(我也有一个头文件,但与这个问题无关)。我必须将它们分开,因为它们会返回不同的列。
问题是我的详细文件有 13,470 行,但是当我在辅助查询(预告文件)中进行计数时,我得到 13,207 行。原因是少数商品具有多个与主要商品 ID 关联的辅助 ID。
如果我不使用SELECT DISTINCT,我可以获得相同的计数,但它会返回 25,250 行。我需要在我的详细信息文件中保留重复项。
详细信息查询很长,但请理解,尽管几乎所有记录都是唯一的,但有些主要项目 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 声明是错误的,但我只是想探索一下它作为一个选项。有谁知道如何让我的查询同步?
再次:
- 微软 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 |
【问题讨论】:
-
您是从这些查询中创建实际文件吗?或者只是结果集。
-
@jderekc:你自己回答了这个问题。您说您在“详细信息”查询中使用
secondary ID,但您没有在“预告片”查询中使用它。如果secondary ID是“详细信息”查询的选择标准的一部分,那么从逻辑上讲,您需要在“预告片”查询中使用secondary ID才能获得相同的计数。 -
您可以做的第二件事:如果您的 'Trailer' 查询总是只返回 1 条记录,您可以在您的 'Detail' 查询之后使用 tsql 函数
@@rowcount。然后您可以将实际的行数放入您的“预告片”中。您需要声明一个整数变量,如:DECLARE @rc as integer;然后在您的“详细”查询之后分配@rc 行数:set @rc = @@rowcount;然后在您的 Trailer 查询中,您可以在您想要行数的地方使用@rc 变量。 -
这些查询结果集将被导出到唯一的文件中。另外,如果您查看我的案例陈述,我会尝试包含两个 ID 以进行比较,但我的逻辑不正确。
-
@jderekc:您可能需要向我们展示您的“详细信息”查询,以便我们了解您的
primary ID和secondary ID的实际使用情况。如果您的“预告片”查询正在删除您的secondary ID记录,那么您的逻辑问题就在那里。
标签: sql sql-server sql-server-2012 count