Reputation: 115
I have two separate queries. One I am using for a details file and the other I am using for the end/trailer file (I also have a header file but that one is irrelevant to this question). I will have to keep these separate as they will return different columns.
The problem is my detail file has 13,470 rows but when I do a count in the secondary query (the trailer file), I get 13,207 rows. The reason is that a few items have multiple secondary IDs associated with the primary item ID.
I can get the same count if I don't use a SELECT DISTINCT
, but it then returns 25,250 rows. I need to keep duplicates out of my details file.
The details query is quite long, but just understand that even though ALMOST all records are unique, there are some where the primary item ID is seemingly duplicated only because the secondary item ID might have a few different values for the primary item ID.
I've read the following articles but can't seem to get any of it to work. Note that I am using Microsoft SQL Server 2012 and not MySQL, but I did apply the concept of MySQL to my needs that was explained in one of the articles:
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
So again, I would like to get a count based on all of the criteria I specified in the details file (dozens of columns and 13,470 rows). My trailer file is only two columns and one row. One to identify that it is the end/trailer file and the other to show the count of records that should have been returned by the details file.
Here's my "just try and see if this works or is on the right path" query (and it doesn't):
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%')
This returns 25,250 rows.
Of course the CASE
statement is wrong, but I just wanted to explore that as an option. Does anyone have any idea on how I can get my queries to sync up?
Again:
Trailer results using CASE
statement:
| RECID | TOTREC |
--------------------
1 | TRL | 25250 |
Trailer results just counting DISTINCT
on one of the columns:
| RECID | TOTREC |
--------------------
1 | TRL | 13207 |
Looking for:
| RECID | TOTREC |
--------------------
1 | TRL | 13470 |
Any advice would be greatly appreciated. Thanks!
EDIT
Here is the Detail file query, but I've removed irrelevant columns; I executed this query and it works the same as the non-edited query, so this should be good enough to tell:
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%')
Note that ITEMNMBR
is the primary, internal ID whereas VNDITNUM
is the vendor/supplier ID, which I call the secondary ID. It is VNDITNUM
that sometimes has more than one record for a unique primary, internal ID of a product.
A normal result would be as follows:
| RECID | COMPANY | VNDITEM | NUMITEM | ITMDESC | STATUS |
------------------------------------------------------------
1 | DTL | 12345 | 011223 | 100234 | Game | A |
2 | DTL | 12345 | 015992 | 104722 | Picture | A |
But here is an example as how it might duplicate:
| RECID | COMPANY | VNDITEM | NUMITEM | ITMDESC | STATUS |
------------------------------------------------------------
1 | DTL | 12345 | 029445 | 109777 | Book A | A |
2 | DTL | 12345 | 029478 | 109777 | Book A | A |
Upvotes: 0
Views: 1055
Reputation: 115
I found a way to do this using a derived table so that I can still keep the queries separate and use SSIS to populate separate flat files (couldn't do this with one query having multiple select statements without UNION
s). Thanks to all for helping me get there! Your suggestions were much appreciated.
Here is what I used:
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%')
Upvotes: 1
Reputation: 701
If your 'Trailer' query only ever returns 1 record... then you can try to use the tsql function @@recordcount
Like this:
-- 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];
This has the added benefit of giving you the row count of the actual query you are interested in having the count of. Plus you don't have to execute duplicate logic which could be time consuming (especially if your Detail query is as complicated as you make it out to be).
Hope that helps :)
Upvotes: 1