我有一张表“Mark”,其中包含不同主题的标记。如果标记符合某个特定范围,那么我应该选择相应的排名并在“rank_sub_1”列中插入标记表本身。你能帮我吗,我怎么能在桌子上查看并插入栏目。下面是我的表结构。
**Marks**
Subject1_Marks Subject2_Marks
------------------------------
71 22
10 40
**LookupTable**
Rank range1 range2
----------------------
9 10 20
8 21 30
7 31 40
6 41 50
5 51 60
4 61 70
3 71 80
2 81 90
1 91 100
现在我想用查找表检查每个主题的标记,查找表包含获得的不同标记的范围和等级。
**Marks**
Subject1_Marks Subject2_Marks Rank_Sub_1 Rank_Sub_2
------------------------------------------------------
71 22
10 40
如果标记符合某个特定范围,那么我应该选择相应的等级并在“rank_sub_1”列中插入标记表本身。你能帮我吗,我怎么能在桌子上查看并插入栏目。
答案 0 :(得分:0)
我认为这个update
语句可以做你想要的:
UPDATE Marks m
SET Rank_Sub_1 = (SELECT l.Rank
FROM LookupTable l
WHERE m.Subject1_Marks BETWEEN l.range1 AND l.range2)
WHERE EXISTS (
SELECT 1
FROM LookupTable l
WHERE m.Subject1_Marks BETWEEN l.range1 AND l.range2
);
如果您想同时更新Rank_Sub_2
的值,可以执行以下操作:
UPDATE Marks m
SET Rank_Sub_1 = (SELECT l.Rank
FROM LookupTable l
WHERE m.Subject1_Marks BETWEEN l.range1 AND l.range2)
,Rank_Sub_2 = (SELECT l.Rank
FROM LookupTable l
WHERE m.Subject2_Marks BETWEEN l.range1 AND l.range2)
答案 1 :(得分:0)
(考虑到范围值没有重叠)
获取两个lookuptable实例,首先使用subject1_marks连接,然后使用subject2_marks连接第二个实例。在这里,我没有使用LEFT JOINS,因为我假设您的主题标记肯定会落在1个范围内。如果您对此不确定,请使用左连接并根据您对RANK_SUB_1和RANK_SUB_2列的要求处理空值
WITH LOOKUPTABLE_TMP AS (SELECT * FROM LOOKUPTABLE)
SELECT M.*, L1.RANK AS RANK_SUB_1, L2.RANK AS RANK_SUB_2
FROM MARKS M , LOOKUPTABLE_TMP L1, LOOKUPTABLE_TMP L2
WHERE M.SUBJECT1_MARKS BETWEEN L1.RANGE1 AND L1.RANGE2
AND M.SUBJECT2_MARKS BETWEEN L2.RANGE1 AND L2.RANGE2
然后将数据合并到表MARKS中。
解决方案:
MERGE INTO MARKS MS
USING
(
SELECT M.SUBJECT1_MARKS, M.SUBJECT2_MARKS, L1.RNK AS RANK_SUB_1, L2.RNK AS RANK_SUB_2
FROM MARKS M , LOOKUPTABLE L1, LOOKUPTABLE L2
WHERE M.SUBJECT1_MARKS BETWEEN L1.RANGE1 AND L1.RANGE2
AND M.SUBJECT2_MARKS BETWEEN L2.RANGE1 AND L2.RANGE2
GROUP BY M.SUBJECT1_MARKS, M.SUBJECT2_MARKS, L1.RNK, L2.RNK
) SUB
ON (MS.SUBJECT1_MARKS=SUB.SUBJECT1_MARKS AND MS.SUBJECT2_MARKS =SUB.SUBJECT2_MARKS)
WHEN MATCHED THEN UPDATE
SET MS.RANK_SUB_1=SUB.RANK_SUB_1, MS.RANK_SUB_2=SUB.RANK_SUB_2;
根据您问题的详细信息对以下架构和数据进行测试。
CREATE TABLE MARKS (SUBJECT1_MARKS NUMBER, SUBJECT2_MARKS NUMBER , RANK_SUB_1 NUMBER, RANK_SUB_2 NUMBER)
INSERT INTO MARKS (SUBJECT1_MARKS , SUBJECT2_MARKS ) VALUES (71, 22);
INSERT INTO MARKS (SUBJECT1_MARKS , SUBJECT2_MARKS ) VALUES (10, 40);
CREATE TABLE LOOKUPTABLE (RNK NUMBER, RANGE1 NUMBER , RANGE2 NUMBER)
INSERT INTO LOOKUPTABLE VALUES (9, 10, 20);
INSERT INTO LOOKUPTABLE VALUES (8, 21, 30);
INSERT INTO LOOKUPTABLE VALUES (7, 31, 40);
INSERT INTO LOOKUPTABLE VALUES (6, 41, 50);
INSERT INTO LOOKUPTABLE VALUES (5, 51, 60);
INSERT INTO LOOKUPTABLE VALUES (4, 61, 70);
INSERT INTO LOOKUPTABLE VALUES (3, 71, 80);
INSERT INTO LOOKUPTABLE VALUES (2, 81, 90);
INSERT INTO LOOKUPTABLE VALUES (1, 91, 100);
谢谢!
答案 2 :(得分:0)
考虑下面的设计,消除了重叠或间隙的可能性。虽然我通常将此技术用于日期,但任何定义完整序列的数据都将以相同的方式工作。这个想法是你只定义范围的起始位置。可以理解,范围在可能的最后值处停止,小于下一个更高的范围。但是,请注意我添加了第十个等级,以防小于10的值。当然,任何大于100的值都将显示为等级1.
with
Lookup( Rank, Cutoff )as(
select 1, 91 union all
select 2, 81 union all
select 3, 71 union all
select 4, 61 union all
select 5, 51 union all
select 6, 41 union all
select 7, 31 union all
select 8, 21 union all
select 9, 10 union all
select 10, 0
),
Marks( Mark1, Mark2 )as(
select 71, 22 union all
select 10, 40 union all
select 21, 101
)
select Mark1, l1.Rank as Rank1, Mark2, l2.Rank as Rank2
from Marks m
join Lookup l1
on l1.Cutoff =(
select Max( Cutoff )
from Lookup
where Cutoff <= m.Mark1 )
join Lookup l2
on l2.Cutoff =(
select Max( Cutoff )
from Lookup
where Cutoff <= m.Mark2 );
输出:
Mark1 Rank1 Mark2 Rank2
----------- ----------- ----------- -----------
71 3 22 8
10 9 40 7
21 8 101 1