SQL服务器 - 高级分组

时间:2012-12-20 11:40:14

标签: sql sql-server sql-server-2008-r2

我在表中包含如下所示的采购合同:

+------+-----------+------------+---------+------------+-----------+
| type | text      | date       | company | supplierID | name      |
+ -----+-----------+------------+---------+------------+-----------+
| 0    | None      | 2004-03-29 | 310     | 227234     | HRC INFRA |
| 0    | None      | 2007-09-30 | 310     | 227234     | HRC INFRA |
| 0    | None      | 2010-11-29 | 310     | 227234     | HRC INFRA |
| 2    | Strategic | 2011-01-01 | 310     | 227234     | HRC INFRA |
| 0    | None      | 2012-04-10 | 310     | 227234     | HRC INFRA |
+------+-----------+------------+---------+------------+-----------+

在这个例子中,前三行的合约是相同的。所以我只想要第一个。 type = 2的行是与给定供应商的采购合同的变更。我也想选择那一行。 在最后一行,合约变回0,所以我也想选择那一行。

基本上我想选择第一行和合约类型更改的行。所以结果应该是这样的:

+------+-----------+------------+---------+------------+-----------+
| type | text      | date       | company | supplierID | name      |
+ -----+-----------+------------+---------+------------+-----------+
| 0    | None      | 2004-03-29 | 310     | 227234     | HRC INFRA |
| 2    | Strategic | 2011-01-01 | 310     | 227234     | HRC INFRA |
| 0    | None      | 2012-04-10 | 310     | 227234     | HRC INFRA |
+------+-----------+------------+---------+------------+-----------+

有关如何实现这一目标的任何建议吗?

3 个答案:

答案 0 :(得分:1)

我没有在我面前测试SQL服务器,所以我现在不打算尝试实际的解决方案,但是你需要的东西很少:

1)确保记录正确排序的方法。我在这里看不到任何类型的ID,这意味着您无法保证它们将以该顺序出现。我假设有一个,所以请确保你订购

2)无论索引是什么,你都需要对表进行外部连接,但不是“table1.index = table2.index”,它看起来像“table1.index = table2.index + 1” 。如果您的索引不是顺序的,那么它将使这种方式更加复杂。

3)在where子句中,您将指定类似

的内容
where table1.type <> table2.type

那会让你最好的方式。虽然因为在第一个记录之前没有记录可以比较,所以这不会获得第一个记录,所以你需要一个OR加法来补偿它。我假设该类型没有NULL值。

对不起,我对实际的实施方式无能为力,但也许其他人很快就会处理这个问题。

答案 1 :(得分:1)

可能就是你想要的。假设你没有类型&lt; 0

SELECT * 
FROM [TABLE] as ot where ot.type <> 
(select top 1 coalesce(it.type, -1) from [TABLE] as it where it.date < ot.date order by it.date desc)

另外,请不要使用brandon note来制作舒尔表,因为我没有看到PK。

答案 2 :(得分:1)

;WITH cte AS
 (
  SELECT ROW_NUMBER() OVER (ORDER BY date) AS Id,
         type, text, date, company, supplierId, name
  FROM your_table
  )
  SELECT c1.type, c1.text, c1.date, c1.company,
         c1.supplierId, c1.name
  FROM cte c1 LEFT JOIN cte c2 ON c1.id = c2.id + 1
  WHERE c2.text IS NULL OR c1.text != c2.text

SQLFiddle上的演示