SQL Count ROWS

3

Good!

I have two tables:

A: PRINTER (ID), DATE, STORAGE, TYPE

B: Autoreg (ID), PRINTER, PRODUCT

And I wanted to have a type result:

TotalCombustible, TotalStore, Mixed

Where the Fuel is when the product is = 1, the Store is > 1 and the mixed is

If I see the rows all of the table I have gives this:

NowImadetheconnectionlikethis:

SELECT(SELECTCOUNT(DISTINCT[VendasPOS_Linhas].[PRENUMERO])FROM[VendasPOS_Linhas]JOIN[VendasPOS_Cabecalhos]ON[VendasPOS_Linhas].[PRENUMERO]=[VendasPOS_Cabecalhos].[PRENUMERO]WHERE[VendasPOS_Cabecalhos].[FACT_VD]like'T'AND[VendasPOS_Cabecalhos].[DATA]>'2015-06-0100:00:00.000'AND[VendasPOS_Cabecalhos].[Armazem]='454'AND[VendasPOS_Linhas].[PRODUTO]>1)ASQtdLoja,(SELECTCOUNT(DISTINCT[VendasPOS_Linhas].[PRENUMERO])FROM[VendasPOS_Linhas]JOIN[VendasPOS_Cabecalhos]ON[VendasPOS_Linhas].[PRENUMERO]=[VendasPOS_Cabecalhos].[PRENUMERO]WHERE[VendasPOS_Cabecalhos].[FACT_VD]like'T'AND[VendasPOS_Cabecalhos].[DATA]>'2015-06-0100:00:00.000'AND[VendasPOS_Cabecalhos].[Armazem]='454'AND[VendasPOS_Linhas].[PRODUTO]=1)ASQtdCombustivel,(SELECTCOUNT(DISTINCT[VendasPOS_Cabecalhos].[PRENUMERO])fromVendasPOS_LinhasJOIN[VendasPOS_Cabecalhos]ON[VendasPOS_Linhas].[PRENUMERO]=[VendasPOS_Cabecalhos].[PRENUMERO]whereDATA>'2015-06-0100:00:00.000'andArmazem='454'AND[VendasPOS_Cabecalhos].[FACT_VD]like'T')ASTotal

Andtheresultgivesthis:

But soon here I see some errors.

1st Total seems to be over.

2º The totalComb and TotalLoja are counting those that are also mixed

3º In line 11 and 12 we can see that it has PREMIUMS the same but the product is both> 1 and in the bottom line = 1 and this is part of the mixed. How do I see if a PRENUMERO both has 1 and> 1 being that it gives different rows. That is, I have to see what the duplicates are and see if the same PRENUMERO has = 1 and> 1 but not if this is possible.

RESOLVED:

SELECT 
    (SELECT COUNT(DISTINCT [VendasPOS_Linhas].[PRENUMERO]) FROM [VendasPOS_Linhas] 
     INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) = 1
        ) combustivel ON combustivel.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
        WHERE [VendasPOS_Linhas].[PRODUTO] = 1
     ) AS QtdeCombustivel,
    (SELECT COUNT(DISTINCT [VendasPOS_Linhas].[PRENUMERO]) FROM [VendasPOS_Linhas] 
     INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) = 1
        ) loja ON loja.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
        WHERE [VendasPOS_Linhas].[PRODUTO] > 1
     ) AS QtdeLoja,
    (SELECT COUNT(DISTINCT [VendasPOS_Linhas].[PRENUMERO]) FROM [VendasPOS_Linhas] 
      INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) > 1
        ) mista ON mista.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
     ) AS QtdeMista
    
asked by anonymous 09.06.2015 / 18:11

2 answers

1

I tried to do a trick with HAVING COUNT , but I do not know if it will work.

SELECT 
    (SELECT COUNT([VendasPOS_Linhas].[PRENUMERO]) FROM [MXPETROL_AB].[dbo].[VendasPOS_Linhas] 
     INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [MXPETROL_AB].[dbo].[VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) = 1
        ) combustivel ON combustivel.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
        WHERE [VendasPOS_Linhas].[PRODUTO] = 1
     ) AS QtdeCombustivel,
    (SELECT COUNT([VendasPOS_Linhas].[PRENUMERO]) FROM [MXPETROL_AB].[dbo].[VendasPOS_Linhas] 
     INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [MXPETROL_AB].[dbo].[VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) = 1
        ) loja ON loja.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
        WHERE [VendasPOS_Linhas].[PRODUTO] > 1
     ) AS QtdeLoja,
     (SELECT COUNT([VendasPOS_Linhas].[PRENUMERO]) FROM [MXPETROL_AB].[dbo].[VendasPOS_Linhas] 
      INNER JOIN
        (
            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [MXPETROL_AB].[dbo].[VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING MIN([VendasPOS_Linhas].[PRODUTO]) = 1 AND MAX([VendasPOS_Linhas].[PRODUTO]) <> 1 AND COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) > 
        ) mista ON mista.PRENUMERO = [VendasPOS_Linhas].[PRENUMERO]
     ) AS QtdeMista

Explanation

Internal SELECT

            SELECT [VendasPOS_Linhas].[PRENUMERO]
            FROM
                [MXPETROL_AB].[dbo].[VendasPOS_Linhas]
            JOIN    [VendasPOS_Cabecalhos]
            ON    [VendasPOS_Linhas].[PRENUMERO] = [VendasPOS_Cabecalhos].[PRENUMERO]
            WHERE
                [VendasPOS_Cabecalhos].[FACT_VD] like 'T' AND
                [VendasPOS_Cabecalhos].[DATA] > '2015-06-01 00:00:00.000' AND 
                [VendasPOS_Cabecalhos].[Armazem] = '454'
            GROUP BY [VendasPOS_Linhas].[PRENUMERO]
            HAVING COUNT(DISTINCT [VendasPOS_Linhas].[PRODUTO]) = 1

Because of HAVING COUNT(...) = 1 will only return PRENUMERO that have 1 single PRODUTO while in last SELECT I > 1 to get PRENUMERO that are mixed

After the return of the SELECT more inside, I make a COUNT(...) to know how many PRENUMERO different returned me.

To know if it is fuel or shop I do at the time of COUNT mentioned above, if it is fuel it is WHERE [VendasPOS_Linhas].[PRODUTO] = 1 while store is WHERE [VendasPOS_Linhas].[PRODUTO] > 1 . In the case of mixed it is indifferent.

    
09.06.2015 / 20:01
1

The question has already been answered but I still leave a more concise answer that avoids the many sub-queries of the original solution.

SELECT    COUNT(DISTINCT CASE WHEN MinProduto = 1 AND MaxProduto = 1 THEN PRENUMERO END) AS QtdCombustivel
         ,COUNT(DISTINCT CASE WHEN MinProduto <> 1 AND MaxProduto <> 1 THEN PRENUMERO END) AS QtdLoja
         ,COUNT(DISTINCT CASE WHEN MinProduto = 1 and MaxProduto <> 1 THEN PRENUMERO END) AS QtdMisto
         ,COUNT(DISTINCT PRENUMERO) AS TotalAbsoluto
FROM
(
    SELECT   VL.PRENUMERO
            ,COUNT(DISTINCT VL.PRODUTO) AS NumProduto
            ,MIN(VL.PRODUTO)            AS MinProduto
            ,MAX(VL.PRODUTO)            AS MaxProduto
    FROM    MXPETROL_AB.dbo.VendasPOS_Linhas VL
    INNER JOIN VendasPOS_Cabecalhos VC
       ON    VL.PRENUMERO = VC.PRENUMERO
    WHERE    VC.FACT_VD = 'T' 
      AND    VC.DATA > '2015-06-01 00:00:00.000' 
      AND    VC.Armazem = '454' 
    GROUP BY VL.PRENUMERO
) Res

I've only changed one of your conditions for

VC.FACT_VD LIKE 'T' 

for

VC.FACT_VD = 'T'

Since you were not using wildcards, the use of LIKE was not justified.

Edit:

As requested in the comments, this query will return the totals per day:

SELECT    DATA
         ,COUNT(DISTINCT CASE WHEN MinProduto = 1 AND MaxProduto = 1 THEN PRENUMERO END) AS QtdCombustivel
         ,COUNT(DISTINCT CASE WHEN MinProduto <> 1 AND MaxProduto <> 1 THEN PRENUMERO END) AS QtdLoja
         ,COUNT(DISTINCT CASE WHEN MinProduto = 1 and MaxProduto <> 1 THEN PRENUMERO END) AS QtdMisto
         ,COUNT(DISTINCT PRENUMERO) AS TotalAbsoluto
FROM
(
    SELECT   VC.DATA 
            ,VL.PRENUMERO
            ,COUNT(DISTINCT VL.PRODUTO) AS NumProduto
            ,MIN(VL.PRODUTO)            AS MinProduto
            ,MAX(VL.PRODUTO)            AS MaxProduto
    FROM    MXPETROL_AB.dbo.VendasPOS_Linhas VL
    INNER JOIN VendasPOS_Cabecalhos VC
       ON    VL.PRENUMERO = VC.PRENUMERO
    WHERE    VC.FACT_VD = 'T' 
      AND    VC.DATA > '2015-06-01 00:00:00.000' 
      AND    VC.Armazem = '454' 
    GROUP BY VC.DATA, VL.PRENUMERO
) Res
GROUP BY DATA
ORDER BY 1
    
09.06.2015 / 22:08