Sql Server查询按名称分组

时间:2012-06-14 09:37:21

标签: sql sql-server join

我有2个表Notes(左)和扫描(右)的以下数据:

enter image description here

想象一下,选择器和打包器都是变化的,就像你可以JOHN, JANE等一样。

我需要一个像这样输出的查询:

在给定的date range上:

Name - Picked (units) - Packed (units)
MASI - 15 - 21
JOHN - 21 - 32

我无法弄清楚如何开始这个,任何提示都会有所帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

SELECT name, SUM(nbPicked) Picked, SUM(nbPacked) Packed
FROM
(SELECT n.Picker name, SUM(n.Units) nbPicked, 0 nbPacked 
FROM Notes n
INNER JOIN scans s ON s.PickNote = n.Number
--WHERE s.ProcessedOn BETWEEN x and y
GROUP BY n.Picker

UNION ALL

SELECT n.Packer name, 0 nbPicked, SUM(n.Units) nbPacked
FROM Notes n
INNER JOIN scans s ON s.PickNote= n.Number
--WHERE s.ProcessedOn BETWEEN x and y
GROUP BY n.Packer)

GROUP BY name;

答案 1 :(得分:1)

如果没有“工人”单独列出每个Picker / Packer,我认为你需要这样的东西......

SELECT
      CASE WHEN action.name = 'Picker' THEN scans.Picker ELSE scans.Packer END  AS worker,
  SUM(CASE WHEN action.name = 'Picker' THEN notes.Units  ELSE 0            END) AS PickedUnits,
  SUM(CASE WHEN action.name = 'Packer' THEN notes.Units  ELSE 0            END) AS PackedUnits
FROM
  notes
INNER JOIN
  scans
    ON scans.PickNote = notes.Number
CROSS JOIN
(
            SELECT 'Picker' AS name
  UNION ALL SELECT 'Packer' AS name

)
  AS action
GROUP BY
  CASE WHEN action.name = 'Picker' THEN scans.Picker ELSE scans.Packer END

(这实际上只是对@RaphaëlAlthaus与我同时发布的答案的代数重新安排。两者都使用UNION分别计算出Picker值和Packer值。如果你在scans.Pickerscans.Packer上有单独的索引然后我希望我的可能是最慢的。如果你没有这两个索引那么我希望我的速度最快。我建议创建索引和测试在一个真实的数据集上。)

修改

实际上,我建议完全改变扫描表;将其标准化。

  • 您的非规范化集合每个PickNote有一行,其中包含字段pickerpacker
  • 规范化集合每个PickNote有两行,字段为roleworker


  id  | PickNote | Role | Worker
------+----------+------+--------
  01  | PK162675 | Pick |  MASI
  02  | PK162675 | Pack |  MASI
  03  | PK162676 | Pick |  FRED
  04  | PK162676 | Pack |  JOHN

这允许您创建简单索引和简单查询。

您最初可能会使用额外的不必要的行,但它会产生更简单的查询,更快的查询,更好的可维护性,更高的灵活性等等。

简而言之,这种规范化可能会花费一点额外的空间,但它会永远带来红利。