2017-08-10 1 views
0

J'ai deux requêtes distinctes. Un que j'utilise pour un fichier de détails et l'autre que j'utilise pour le fichier fin/trailer (j'ai aussi un fichier d'en-tête mais celui-ci n'est pas pertinent pour cette question). Je vais devoir les séparer car ils renverront des colonnes différentes.Deux requêtes distinctes; il faut compter les lignes de l'autre

Le problème est mon fichier de détail a 13 470 lignes, mais quand je fais un compte dans la requête secondaire (le fichier de la remorque), je reçois 13 207 lignes. La raison en est que quelques éléments ont plusieurs identifiants secondaires associés à l'ID de l'élément principal.

Je peux obtenir le même nombre si je n'utilise pas un SELECT DISTINCT, mais il renvoie ensuite 25 250 lignes. Je dois garder les doublons hors de mon fichier de détails. La requête de détails est assez longue, mais comprenez que même si PRESQUE tous les enregistrements sont uniques, il y en a où l'ID de l'élément principal est apparemment dupliqué uniquement parce que l'ID article secondaire peut avoir plusieurs valeurs différentes pour l'élément principal. ID.

J'ai lu les articles suivants, mais je n'arrive pas à faire fonctionner tout ça. Notez que j'utilise Microsoft SQL Server 2012 et non MySQL, mais je n'applique le concept de MySQL à mes besoins qui a été expliqué dans l'un des 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

Encore une fois, j'aimerais obtenir un décompte basé sur tous les critères que j'ai spécifiés dans le fichier de détails (des dizaines de colonnes et 13 470 lignes). Mon fichier de remorque est seulement deux colonnes et une rangée. Un pour identifier qu'il s'agit du fichier de fin/de fin et l'autre pour afficher le nombre d'enregistrements qui auraient dû être renvoyés par le fichier de détails.

Voici mon « juste essayer et voir si cela fonctionne ou est sur la bonne voie » requête (et il ne fonctionne pas):

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%') 

Ce retourne 25.250 lignes.

Bien sûr, l'instruction CASE est erronée, mais je voulais juste l'explorer en tant qu'option. Est-ce que quelqu'un a une idée sur comment synchroniser mes requêtes?

Encore une fois:

  • Microsoft SQL Server 2012
  • 1 fichier d'en-tête (travaux)
  • 1 Détails du fichier (travaux)
  • 1 Fichier de remorque (ne fonctionne pas comme prévu)

Résultats de la remorque utilisant CASE déclaration:

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

résultats Trailer sur DISTINCT ne comptant que l'une des colonnes:

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

Recherche:

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

Tout conseil serait grandement appréciée. Merci!

EDIT

Voici la requête de fichier de détail, mais j'ai supprimé les colonnes non pertinentes; J'ai exécuté cette requête et fonctionne de la même que la requête non modifiée, ce qui devrait être assez bon pour dire:

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%') 

Notez que ITEMNMBR est le primaire, ID interne alors que VNDITNUM est le fournisseur/ID fournisseur, que j'appelle l'ID secondaire. C'est VNDITNUM qui a parfois plus d'un enregistrement pour un ID interne primaire unique d'un produit.

Un résultat normal serait la suivante:

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

Mais voici un exemple que la façon dont il pourrait faire double emploi:

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

vous créez des fichiers réels de ces questions? Ou juste des ensembles de résultats. – HLGEM

+0

@jderekc: Vous avez répondu à la question vous-même. Vous dites que vous utilisez le 'ID secondaire 'dans votre requête' Détail ', mais vous ne l'utilisez pas dans votre requête' Trailer '. Si le 'ID secondaire 'fait partie de vos critères de sélection pour la requête' Détail ', alors logiquement, il vous faudra l'ID' secondaire 'dans votre requête' Trailer 'pour obtenir le même nombre. – abraxascarab

+0

Une deuxième chose que vous pouvez faire: Si votre requête 'Trailer' renvoie toujours seulement 1 enregistrement, vous pouvez utiliser la fonction tsql '@@ rowcount' juste après votre requête 'Detail'. Ensuite, vous pouvez simplement placer le rowcount réel dans votre 'Trailer'. Vous devez déclarer une variable entière, comme dans: 'DECLARE @rc comme entier;' Ensuite, après votre requête 'Detail', attribuez @rc le rowcount: 'set @rc = @@ rowcount;' Ensuite, dans votre requête Trailer vous pouvez utilisez la variable @rc où vous voulez que votre nombre de lignes. – abraxascarab

Répondre

1

Si votre « remorque », requête renvoie jamais 1 enregistrement .. . vous pouvez essayer d'utiliser la fonction tsql @@recordcount

Comme ceci:

-- 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]; 

Cela a l'avantage supplémentaire de vous donner le nombre de lignes de la requête réelle qui vous intéresse. De plus, vous n'avez pas besoin d'exécuter une logique en double, ce qui peut prendre beaucoup de temps (en particulier si votre requête de détail est aussi compliquée que vous le pensez).

Hope that helps :)

+0

Cela fonctionne réellement, merci! Je ne sais pas encore comment je vais exporter cela dans plusieurs fichiers, mais je ne l'ai pas encore essayé. – jderekc

1

J'ai trouvé une façon de le faire en utilisant une table dérivée afin que je puisse toujours garder les requêtes distinctes et utiliser SSIS pour remplir des fichiers plats séparés (ne pouvait pas le faire avec une requête avoir plusieurs instructions select sans UNION s). Merci à tous pour m'avoir aidé à y aller! Vos suggestions ont été très appréciées.

Voici ce que je:

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%')