我无法判断我的特定情况是否已经涵盖了其他问题的标题,如果答案已经存在,那么道歉。
我有一个数据库,它将值记录为字符串,另一个表记录了这些值中特定类型的运行。
我需要一个迭代值的存储过程(我理解这与游标的概念有关),将每个值记录到临时表以控制特定运行类型的计数(奇数/偶数,例如,或元音/辅音)。当给定值指示特定类型的运行已停止时(即奇数停止了偶数运行,反之亦然),运行计数,计数被插入到具有相关类型值的运行表中(0 = odd / even,1 =元音/辅音等),删除临时表内容,并将导致表计数/清除的值插入临时表。
由于我对存储过程完全不熟悉,我不知道如何构建这种过程,我发现的例子不是:
如果有任何需要澄清,请告诉我。
编辑:
正在使用的版本:MS SQL Server 2012
原始值的表结构:
ID: Int PK AI
DateTimeStamp: Datetime
SelectedValue: Char(2)
UserId: Int
值运行的表结构:
ID: Int PK AI
DateTimeStamp: Datetime
Type: Int
Run: Int
示例数据:[以下以逗号分隔的字符串显示,为简洁起见,由一位用户输入]
e,00,1,t,r,2,4,3,5,7,a,i,w,q,u,o,23,25,24,36,12,e ... < / p>
组将是:
vowels/consonants
even numbers/odd numbers
00
numbers under/over 20
numbers/letters
从上面来看,运行是:
e (vowels/consonants: vowels)
e (numbers/letters: letters)
00 (00)
1 (odd/even: odd)
1 (numbers/letters: numbers)
t, r (vowels/consonants: consonants)
t, r (numbers/letters: letters)
2, 4 (odd/even: even)
3, 5, 7 (odd/even: odd)
2, 4, 3, 5, 7 (numbers/letters: numbers)
a, i (vowels/consonants: vowels)
w, q (vowels/consonants: consonants)
a, i, w, q, u, o (numbers/letters: letters)
1, 2, 4, 3, 5, 7 (under/over 20: under 20)
23, 25 (odd/even: odd)
23, 25, 24, 36 (under/over 20: over 20)
24, 36, 12 (odd/even: even)
u, o, e (vowels/consonants: vowels)
这将使运行表的条目为
Type: vowels/consonants, run: 1
Type: numbers/letters, run: 1
Type: 00, run: 1
Type: odd/even, run: 1
Type: numbers/letters, run: 1
Type: odd/even, run: 2
Type: odd/even, run: 3
Type: numbers/letters, run: 5
Type: vowels/consonants, run: 2
Type: vowels/consonants, run: 2
Type: numbers/letters, run: 6
Type: under/over 20, run: 6
Type: odd/even, run: 2
Type: under/over 20, run: 4
Type: odd/even, run: 3
Type: vowels/consonants, run: 3
答案 0 :(得分:1)
编辑根据原始问题的说明进行了更新。
这可能不是最干净的解决方案,但它应该让你开始:
WITH cteClassifications (ID, GroupNo, Type, Description) As
(
-- Vowels:
SELECT
ID,
1,
1,
'Vowels'
FROM
RawData
WHERE
SelectedValue In ('a', 'e', 'i', 'o', 'u')
UNION ALL
-- Consonants:
SELECT
ID,
1,
2,
'Consonants'
FROM
RawData
WHERE
SelectedValue Between 'a' And 'z'
And
SelectedValue Not In ('a', 'e', 'i', 'o', 'u')
UNION ALL
-- Even numbers:
SELECT
ID,
2,
1,
'Even numbers'
FROM
RawData
WHERE
SelectedValue != '00'
And
SelectedValue Not Between 'a' And 'z'
And
(TRY_PARSE(SelectedValue As tinyint) & 1) = 0
UNION ALL
-- Odd numbers:
SELECT
ID,
2,
2,
'Odd numbers'
FROM
RawData
WHERE
SelectedValue != '00'
And
SelectedValue Not Between 'a' And 'z'
And
(TRY_PARSE(SelectedValue As tinyint) & 1) = 1
UNION ALL
-- "00":
SELECT
ID,
3,
1,
'"00"'
FROM
RawData
WHERE
SelectedValue = '00'
UNION ALL
-- Numbers under 20:
SELECT
ID,
4,
1,
'Numbers under 20'
FROM
RawData
WHERE
SelectedValue != '00'
And
SelectedValue Not Between 'a' And 'z'
And
TRY_PARSE(SelectedValue As tinyint) < 20
UNION ALL
-- Numbers over 20:
SELECT
ID,
4,
2,
'Numbers over 20'
FROM
RawData
WHERE
SelectedValue != '00'
And
SelectedValue Not Between 'a' And 'z'
And
TRY_PARSE(SelectedValue As tinyint) > 20
UNION ALL
-- Numbers:
SELECT
ID,
5,
1,
'Numbers'
FROM
RawData
WHERE
SelectedValue != '00'
And
SelectedValue Not Between 'a' And 'z'
And
TRY_PARSE(SelectedValue As tinyint) Is Not Null
UNION ALL
-- Letters:
SELECT
ID,
5,
2,
'Letters'
FROM
RawData
WHERE
SelectedValue Between 'a' And 'z'
),
cteOrderedClassifications (ID, GroupNo, Type, Description, PrevType, RN) As
(
SELECT
ID,
GroupNo,
Type,
Description,
LAG(Type, 1, 0) OVER (PARTITION BY GroupNo ORDER BY ID),
ROW_NUMBER() OVER (PARTITION BY GroupNo ORDER BY ID)
FROM
cteClassifications
),
cteGroupedClassifications (ID, GroupNo, Type, Description, RN, ORN) As
(
SELECT
ID,
GroupNo,
Type,
Description,
RN,
RN
FROM
cteOrderedClassifications As C
WHERE
Type != PrevType
UNION ALL
SELECT
C.ID,
G.GroupNo,
G.Type,
G.Description,
G.RN,
C.RN
FROM
cteGroupedClassifications As G
INNER JOIN cteOrderedClassifications As C
ON C.GroupNo = G.GroupNo
And C.Type = G.Type
And C.RN = G.ORN + 1
),
cteRuns (ID, GroupNo, Type, Description, RN, Run) As
(
SELECT
Min(ID),
GroupNo,
Type,
MAX(Description),
RN,
Count(1)
FROM
cteGroupedClassifications
GROUP BY
GroupNo,
Type,
RN
)
SELECT
ROW_NUMBER() OVER (ORDER BY ID) As ID,
GroupNo,
Type,
Description,
Run
FROM
cteRuns
ORDER BY
ID
;
如果您对查询有效感到满意,可以将最终的SELECT
替换为INSERT INTO Runs (ID, Type, Run) SELECT ID, Type, Run FROM cteFinalRuns
,以便一次性填充表格。