2017-09-25 2 views
1

J'ai validationErrors avec divers WIPReason associés et je veux compter en fonction de WIPReason différent, j'utilise Union All et cela fonctionne mais Query est très grande avec plusieurs raisons de wip plus à 10. S'il vous plaît trouver la requête ci-dessousCompte pour la valeur multiple dans la table sans union tout en sql

SELECT  
    COUNT(tlv.TransactionLineId) AS TotalErrors, 
    COUNT(tl.Id) AS TotalLines, 
    COUNT(tlv.Reason) AS NoWorkRecords, 
    0 AS ValidationErrors 
FROM 
    dbo.TimesheetCellTransactionLine tctl 
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id 
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId 
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id 
WHERE 
    tl.CurrentStatus = 1 
    AND w.Id = 4 -- NoWorkRecords 
GROUP BY 
    tlv.TransactionLineId, tl.Id 

UNION ALL 

SELECT 
    COUNT(tlv.TransactionLineId) AS TotalErrors, 
    COUNT(tl.Id) AS TotalLines, 
    0 AS NoWorkRecords, 
    COUNT(tlv.Reason) AS ValidationErrors 
FROM 
    dbo.TimesheetCellTransactionLine tctl 
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id 
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId 
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id 
WHERE 
    tl.CurrentStatus = 1 
    AND w.Id = 1 -- validationErrors 
GROUP BY 
    tlv.TransactionLineId, tl.Id 

est-il une autre façon élégante de le faire pour w.Id = 1 à 10

ET w.Id = 1 - validationErrors

Mise à jour: Je veux des résultats en tant que colonnes 10 colonnes de compte que j'utilise ceci dans un autre grand choix.

+0

partition essayer par w.id –

+0

Ajouter 'w.Id' à la liste' select', 'et w.Id> = 1 et w.Id <= 10 'à la clause' where' à la place de 'AND w.Id = 4' si vous avez besoin de limiter la plage, et' w.Id' à l'endroit approprié dans le 'group by'. Vous pouvez également ajouter une clause 'order by'. – HABO

Répondre

1

Vous pouvez utiliser une instruction case à l'intérieur count comme ceci:

SELECT  
    COUNT(tlv.TransactionLineId) AS TotalErrors, 
    COUNT(tl.Id) AS TotalLines, 
    COUNT(case when w.Id = 4 then tlv.Reason else null end) AS NoWorkRecords, 
    COUNT(case when w.Id = 1 then tlv.Reason else null end) AS ValidationErrors, 
    ... Repeat for remaining w.Id's ... 
FROM 
    dbo.TimesheetCellTransactionLine tctl 
INNER JOIN 
    dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id 
INNER JOIN 
    dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId 
INNER JOIN 
    dbo.WIPReason w ON tlv.Reason = w.Id 
WHERE 
    tl.CurrentStatus = 1 
GROUP BY 
    tlv.TransactionLineId, tl.Id 

Remarque Puisque vous utilisez un inner join on tl.Id = tlv.TransactionLineId

  1. TotalErrors/TotalLines vont toujours être le même
  2. Regroupement par tl.Id et tlv.TransactionLineId est inutile
1
SELECT COUNT(tlv.TransactionLineId) OVER (partition by (w.Id) order by w.Id) AS TotalErrors, 
     COUNT(tl.Id) OVER (partition by (w.Id) order by w.Id) AS TotalLines, 
     0 AS NoWorkRecords, 
     COUNT(tlv.Reason) OVER (partition by (w.Id) order by w.Id) AS ValidationErrors 
FROM dbo.TimesheetCellTransactionLine tctl 
    INNER JOIN dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id 
    INNER JOIN dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId 
    INNER JOIN dbo.WIPReason w ON tlv.Reason = w.Id 
WHERE tl.CurrentStatus = 1 
     AND w.Id between 1 and 10 -- validationErrors 
GROUP BY tlv.TransactionLineId, 
     tl.Id,tlv.Reason 
+0

Cela me donnera 10 lignes - ce que je veux est de 10 colonnes comme compte parce que j'utilise cette requête dans un autre grand choix. – jjj

+1

vous devez faire pivoter les lignes en colonnes, et cela devrait être assez facile –