可以说我有下表:
| ... | orderId | serialNumber | type | ... |
|-----|---------|--------------|---------------|-----|
| ... | 1 | 01 | someType | ... |
| ... | 1 | 02 | someType | ... |
| ... | 1 | 03 | someOtherType | ... |
| ... | 1 | 04 | someOtherType | ... |
| ... | 1 | 05 | someType | ... |
| ... | 1 | 06 | someType | ... |
| ... | 2 | 07 | someType | ... |
| ... | 2 | 08 | someType | ... |
我希望我的查询生成以下结果:
| orderId | count | min | max | type |
|---------|-------|-----|-----|---------------|
| 1 | 2 | 01 | 02 | someType |
| 1 | 2 | 03 | 04 | someOtherType |
| 1 | 2 | 05 | 06 | someType |
| 2 | 4 | 07 | 08 | someType |
我想要按类型和orderId分组。当serialNumber不在进行时,应创建一个新条目。
这是我当前的查询:
SELECT
orderId,
count(*) AS count,
min(serialNumber) AS min,
max(serialNumber) AS max,
type
FROM tblMyTable
group by type, orderId
order by orderId
但是它创建的结果是错误的:
| orderId | count | min | max | type |
|---------|-------|-----|-----|---------------|
| 1 | 4 | 01 | 06 | someType | <-- this should be 2 entries
| 1 | 2 | 03 | 04 | someOtherType |
| 2 | 2 | 07 | 08 | someType |
如您所见,它没有检测到序列号03和04属于另一个描述。这会导致错误的计数和最大值。
我不知道如何添加检查连续序列号的条件。
编辑: 也可能出现单个记录,例如:
| orderId | count | min | max | type |
|---------|-------|-----|-----|---------------|
| 1337 | 1 | 10 | 10 | someNewType |
答案 0 :(得分:3)
这是一个间隙和孤岛的问题,但是我将使用行数差异方法:
select orderid, count(*), min(serialNumber), max(serialNumber), type
from (select t.*,
row_number() over (partition by orderid order by serialnumber) as seqnum,
row_number() over (partition by orderid, type order by serialnumber) as seqnum_type
from t
) t
group by orderid, type, (seqnum - seqnum_type)
order by orderid, min(serialNumber);
您的serialnumber
看起来像一个字符串,但是具有数字值。如果您可以相信它的排序,那么您甚至都不需要两个行号值:
select orderid, count(*), min(serialNumber), max(serialNumber), type
from (select t.*,
row_number() over (partition by orderid, type order by serialnumber) as seqnum_type
from t
) t
group by orderid, type, (serialnumber - seqnum_type)
order by orderid, min(serialNumber);
此工作的原因很难解释,但如果运行子查询,则很明显。您将看到行号之间的差异如何标识您要标识的组。
答案 1 :(得分:2)
这里还有另一个选择,假设[serialNumber]
指定了顺序。
这通常称为差距与岛屿问题
示例
;with cte as (
Select *
,Grp = sum(Flg) over (order by [serialNumber])
From (
Select *
,Flg = case when concat(orderid,type)<> lag(concat(orderid,type),1) over (Order by [serialNumber]) then 1 else 0 end
From YourTable
) A
)
Select [orderid]
,[count] = count(*)
,[min] = min ([serialNumber])
,[max] = max ([serialNumber])
,[type] = max([type])
From cte
Group by [orderid],Grp
返回
orderid count min max type
1 2 01 02 someType
1 2 03 04 someOtherType
1 2 05 06 someType
2 2 07 08 someType
答案 2 :(得分:0)
这可能需要一些运行,但这只是一个开始。
with cte as (
SELECT *, row_number() over (partition by type, orderId order by serialNumber) as rn
FROM Table1
)
SELECT *
FROM cte c1
LEFT JOIN cte c2
ON c1.orderId = c2.orderId
AND c1.type = c2.type
AND c1.rn = c2.rn-1
AND c1.rn % 2 = 1
输出
+----+---------+--------------+---------------+----+---------+--------------+---------------+------+
| | orderId | serialNumber | type | rn | orderId | serialNumber | type | rn |
+----+---------+--------------+---------------+----+---------+--------------+---------------+------+
| 1 | 1 | 3 | someOtherType | 1 | 1 | 4 | someOtherType | 2 |
| 2 | 1 | 4 | someOtherType | 2 | NULL | NULL | NULL | NULL |
| 3 | 1 | 1 | someType | 1 | 1 | 2 | someType | 2 |
| 4 | 1 | 2 | someType | 2 | NULL | NULL | NULL | NULL |
| 5 | 1 | 5 | someType | 3 | 1 | 6 | someType | 4 |
| 6 | 1 | 6 | someType | 4 | NULL | NULL | NULL | NULL |
| 7 | 2 | 7 | someType | 1 | 2 | 8 | someType | 2 |
| 8 | 2 | 8 | someType | 2 | NULL | NULL | NULL | NULL |
+----+---------+--------------+---------------+----+---------+--------------+---------------+------+