1

我最近遇到了一个关于计算行数的问题。

我正在使用的表格有很多文章,每个文章都与一个运动相关联,而运动又属于一个用户。通常,要计算每个用户有多少不同的动作,我会这样做:

SELECT Mov.Usuario, COUNT(DISTINCT Mov.MovID)
FROM Mov
WHERE Mov.Mov = 'Requisicion'
GROUP BY Mov.Usuario

这给了我一个类似的表:

在此处输入图像描述

但是,我还需要在此表中包含每篇文章的数据以及运动的 ID,如下所示:

在此处输入图像描述

修剪结果以仅显示用户 CGARCIA 的行

有必要与其他表进行一些连接以获得第三列,所以......为了获得前三列,我运行了这个查询:

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1
FROM Mov
INNER JOIN CompraD
ON Mov.ID = CompraD.ID
INNER JOIN Art
ON CompraD.Articulo = Art.Articulo
WHERE Mov.Mov = 'Requisicion'

现在的问题是......我如何获得第四列来计算每个用户有多少不同的 MovID?尝试在SELECT部分的末尾添加COUNT (DISTINCT Mov.MovID)并在查询末尾添加GROUP BY Mov.MovID会引发错误,说:

“选择列表中的列 'Mov.MovID' 无效,因为它不包含在聚合函数中,或者”

是的,它像这样在中间切断。

另外一个问题是,这个 SQL 语句是从外部程序调用的,它允许按日期过滤结果。为此,它会显示一个询问开始和结束日期的表单,并在查询末尾附加一个WHERE条件,如下所示:

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1
FROM Mov
INNER JOIN CompraD
ON Mov.ID = CompraD.ID
INNER JOIN Art
ON CompraD.Articulo = Art.Articulo
WHERE Mov.Mov = 'Requisicion'
AND Mov.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB' -- This is the line added by the system

我无法控制这一点,也无法将参数添加到查询中,因为它们是由程序编写的。我可以让程序在条件之后的末尾添加一个GROUP BY 。

我试过做一些事情,比如用数据获取表,并将它与包含行的表连接起来,但是由于程序在最后添加了过滤条件,所以计数结果不会受到影响并计算所有行。

我怎么能解决这个问题?

4

2 回答 2

1

尝试这个:

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1, cntMov.CountCol
FROM Mov m1
INNER JOIN CompraD c ON m1.ID = c.ID
INNER JOIN Art a ON c.Articulo = a.Articulo
OUTER APPLY 
(
   SELECT COUNT(DISTINCT x.MovID) CountCol
   FROM Mov x
   WHERE x.Mov = m1.Mov
   GROUP BY x.Usuario
) cntMov
WHERE m1.Mov = 'Requisicion'
AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'

编辑: 

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1,  
COUNT(*) OVER (PARTITION BY Mov.Usuario) Cnt
FROM Mov m1
INNER JOIN CompraD c ON m1.ID = c.ID
INNER JOIN Art a ON c.Articulo = a.Articulo   
WHERE m1.Mov = 'Requisicion'
AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'
于 2013-05-15T19:06:08.160 回答
0

为了处理 DISTINCT 问题,试试这个(来自 Plamen Ratchev 的想法):

WITH MovRanked AS (
  SELECT
    Mov.Usuario, Mov.MovID, Art.Descripcion1,
    DENSE_RANK() OVER (
      PARTITION BY Mov.Usario
      ORDER BY Mov.MovID
    ) AS rk
  FROM Mov m1
  INNER JOIN CompraD c ON m1.ID = c.ID
  INNER JOIN Art a ON c.Articulo = a.Articulo   
  WHERE m1.Mov = 'Requisicion'
  AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'
)
  SELECT
    Usario, MovID, Descripcion1,
    MAX(rk) over (PARTITION BY Usario) as MovIDcount
  FROM MovRanked
于 2013-05-16T17:44:21.487 回答