在TSQL上使用INNER JOIN时重复计算结果

时间:2018-11-09 18:35:38

标签: sql sql-server tsql

我正在使用以下查询来统计所有脚本的运行,但是当一种软件有两种类型时,它会使计数结果加倍。

这是我正在使用的查询:

SELECT 
    p.produto, p.pacote, 
    COUNT(p.produto) AS Execuções, 
    CONVERT(VARCHAR, AVG(DATEDIFF(SECOND, p.inicio, p.fim)) / 60) + ':' + RIGHT('0' + CONVERT(VARCHAR, AVG(DATEDIFF(SECOND, p.inicio, p.fim)) % 60), 2) AS [Tempo Médio (Automatizado)], 
    t.tempo_minutos AS [Tempo Médio (Manual)], 
    CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) / 60) + ':' + RIGHT('0' + CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) % 60), 2) AS [Economia Média], 
    CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) * COUNT(p.produto) / 60)  + ':' + RIGHT('0' + CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) * COUNT(p.produto) % 60), 2) AS [Economia Total]
FROM 
    [log].pdq AS p 
INNER JOIN 
    infra.tempo_medio_execucao AS t ON t.produto = p.produto
WHERE 
    (p.equipamento NOT LIKE 'XXX%') AND (p.status = 'Sucesso')
GROUP BY 
    p.produto, p.pacote, t.tempo_minutos

此查询返回以下结果(从表中删除了不必要的信息):

produto  | pacote        | Execuções
---------+---------------+-----------    
SafeSign | Desinstalação | 6
SafeSign | Instalação    | 18
ScanBack | Instalação    | 128

它应该返回的位置:

produto  | pacote        |  Execuções
---------+---------------+-----------    
SafeSign | Desinstalação | 3
SafeSign | Instalação    | 9
ScanBack | Instalação    | 128

在infra.tempo_medio_execucao表中,我有以下数据:

produto      | pacote        | tempo_minutos 
-------------+---------------+--------------
ScanBack     | Instalação    | 20
Siric Zero   | Instalação    | 20
GRRF         | Instalação    | 90
SICCH        | Instalação    | 15
Outlook 2013 | Instalação    | 25
7-Zip        | Instalação    | 20
7-Zip        | Desinstalação | 20
SafeSign     | Instalação    | 20
SafeSign     | Desinstalação | 20

表log.pdq将返回:

id | produto   | pacote      | inicio                  | fim                     | duracao          | status 
---+-----------+-------------+-------------------------+-------------------------+------------------+--------
1  | ScanBack  | Instalação  | 2018-09-18 11:22:54.000 | 2018-09-18 11:27:43.000 | 00:04:49.0000000 | Sucesso 
2  | ScanBack  | Instalação  | 2018-09-18 12:10:46.000 | 2018-09-18 12:11:04.000 | 00:00:17.0000000 | Sucesso 
3  | ScanBack  | Instalação  | 2018-09-18 12:10:49.000 | 2018-09-18 12:11:17.000 | 00:00:27.0000000 | Sucesso 
4  | GRRF      | Instalação  | 2018-09-18 12:28:43.000 | 2018-09-18 12:29:14.000 | 00:00:30.0000000 | Sucesso

我创建的视图返回:(但对于Safesign,它应该返回3和9,而不是6和18)

Produto    |  Pacote       | Execuções  | Tempo Médio (Automatizado) | Tempo Médio (Manual) | Economia Média  | Economia Total
-----------+---------------+------------+----------------------------+----------------------+-----------------+----------------
GRRF       | Instalação    | 1          | 0:31                       | 90                   | 89:29           | 89:29
SafeSign   | Desinstalação | 6          | 0:00                       | 20                   | 20:00           | 120:00
SafeSign   | Instalação    | 18         | 1:19                       | 20                   | 18:41           | 336:18
ScanBack   | Instalação    | 128        | 1:23                       | 20                   | 18:37           | 2382:56
SICCH      | Instalação    | 7          | 0:34                       | 15                   | 14:26           | 101:02
Siric Zero | Instalação    | 208        | 0:33                       | 20                   | 19:27           | 4045:36

谢谢!

2 个答案:

答案 0 :(得分:0)

您的问题中确实缺少某些内容。这似乎产生了正确的结果。因此,我认为您需要提供一个更好的例子。

DECLARE @pdq TABLE (
    ID int,produto nvarchar(50),pacote nvarchar(50),inicio datetime2,fim datetime2,duracao time, status nvarchar(50),equipamento nvarchar(50)
)

DECLARE @tempo_medio_execucao  TABLE (
    produto nvarchar(50),pacote nvarchar(50),tempo_minutos INT
)

INSERT INTO @pdq(id,produto,pacote,inicio,fim,duracao,status,equipamento) SELECT 1,'ScanBack','Instalação','2018-09-18 11:22:54.000','2018-09-18 11:27:43.000','00:04:49.0000000','Sucesso','Unknown'
INSERT INTO @pdq(id,produto,pacote,inicio,fim,duracao,status,equipamento) SELECT 2,'ScanBack','Instalação','2018-09-18 12:10:46.000','2018-09-18 12:11:04.000','00:00:17.0000000','Sucesso','Unknown'
INSERT INTO @pdq(id,produto,pacote,inicio,fim,duracao,status,equipamento) SELECT 3,'ScanBack','Instalação','2018-09-18 12:10:49.000','2018-09-18 12:11:17.000','00:00:27.0000000','Sucesso','Unknown'
INSERT INTO @pdq(id,produto,pacote,inicio,fim,duracao,status,equipamento) SELECT 4,'GRRF','Instalação','2018-09-18 12:28:43.000','2018-09-18 12:29:14.000','00:00:30.0000000','Sucesso','Unknown'

INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'ScanBack','Instalação',20
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'Siric Zero','Instalação',20
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'GRRF','Instalação',90
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'SICCH','Instalação',15
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'Outlook 2013','Instalação',25
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT '7-Zip','Instalação',20
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT '7-Zip','Desinstalação',20
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'SafeSign','Instalação',20
INSERT INTO @tempo_medio_execucao(produto,pacote,tempo_minutos) SELECT 'SafeSign','Desinstalação',20

SELECT 
    p.produto, p.pacote, 
    COUNT(p.produto) AS Execuções, 
    CONVERT(VARCHAR, AVG(DATEDIFF(SECOND, p.inicio, p.fim)) / 60) + ':' + RIGHT('0' + CONVERT(VARCHAR, AVG(DATEDIFF(SECOND, p.inicio, p.fim)) % 60), 2) AS [Tempo Médio (Automatizado)], 
    t.tempo_minutos AS [Tempo Médio (Manual)], 
    CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) / 60) + ':' + RIGHT('0' + CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) % 60), 2) AS [Economia Média], 
    CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) * COUNT(p.produto) / 60)  + ':' + RIGHT('0' + CONVERT(VARCHAR, (t.tempo_minutos * 60 - AVG(DATEDIFF(SECOND, p.inicio, p.fim))) * COUNT(p.produto) % 60), 2) AS [Economia Total]
FROM @pdq AS p 
INNER JOIN @tempo_medio_execucao AS t ON t.produto = p.produto
WHERE (p.equipamento NOT LIKE 'XXX%') AND (p.status = 'Sucesso')
GROUP BY 
    p.produto, p.pacote, t.tempo_minutos

答案 1 :(得分:0)

我怀疑这是否符合您在问题中指定的内容:

SELECT p.produto, p.pacote, 
       COUNT(DISTINCT p.produto) AS Execuções, 
       . . .

您将从联接中得到重复的内容-基本上是意外的匹配。

但是,(很可能)其他列也很不准确。如果这可以解决Execuções的问题,但是您仍然有其他问题,请问另一个问题。要非常清楚样本数据,所需结果以及需要解决的问题。