问题描述
||
一个同义词库,其中的术语和类别相互链接并运行sql Server 2008。
基于此和此答案。这是一个示例:
CREATE TABLE #term (termid VARCHAR(8),en VARCHAR(32),enscope VARCHAR(32))
CREATE TABLE #link (linkid VARCHAR(10),termid VARCHAR(8),reltype VARCHAR(2),refid VARCHAR(8))
CREATE TABLE #categorylink (code VARCHAR(3),termid VARCHAR(8))
INSERT INTO #term VALUES (\'100\',\'ABC\',\'abc_scopenote\')
INSERT INTO #term VALUES (\'120\',\'DEF\',\'def_scopenote\')
INSERT INTO #term VALUES (\'150\',\'GHI\',NULL)
INSERT INTO #link VALUES (\'1\',\'100\',\'NT\',\'120\')
INSERT INTO #link VALUES (\'2\',\'150\')
INSERT INTO #link VALUES (\'3\',\'120\',\'BT\',\'100\')
INSERT INTO #link VALUES (\'4\',\'RT\',\'150\')
INSERT INTO #link VALUES (\'5\',\'150\',\'100\')
INSERT INTO #link VALUES (\'6\',\'120\')
INSERT INTO #categorylink VALUES (\'S01\',\'100\')
INSERT INTO #categorylink VALUES (\'S02\',\'100\')
INSERT INTO #categorylink VALUES (\'B04\',\'150\')
SELECT
CASE
WHEN #term.enscope IS NULL AND refterm.en IS NULL AND #categorylink.code IS NULL
THEN #term.en
ELSE NULL
END,CHAR(9) + \'SN \' + #term.enscope,CHAR(9) + #link.reltype + CHAR(32) + refterm.en,CHAR(9) + \'CODE \' + #categorylink.code
FROM #link
INNER JOIN #term ON #term.termid = #link.termid
INNER JOIN #term AS refterm ON refterm.termid = #link.refid
LEFT JOIN #categorylink ON #term.termid = #categorylink.termid
GROUP BY GROUPING SETS (#term.en,(#term.en,#term.enscope),#link.linkid,#link.reltype,refterm.en),#categorylink.code))
ORDER BY #term.en,#categorylink.code,#term.enscope
GO
DROP TABLE #term
DROP TABLE #link
DROP TABLE #categorylink
GO
如果\'enscope \'中为NULL,则表示行重复。
如果没有\'categorylink \'值,那么我有重复的行。
请如何避免这种情况?
我想将它们全部合并到一个没有重复的列中。
; WITH CTEterm AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY #term.en,refterm.en ORDER BY #term.en) AS rownumber,#term.en AS mainterm,CHAR(9) + \'SN \' + #term.enscope AS scopenote,CHAR(9) + #link.reltype + CHAR(32) + refterm.en AS subterms,CHAR(9) + \'CODE \' + #categorylink.code AS codes
FROM #link
INNER JOIN #term ON #term.termid = #link.termid
INNER JOIN #term AS refterm ON refterm.termid = #link.refid
LEFT JOIN #categorylink ON #term.termid = #categorylink.termid
)
SELECT COALESCE(
CASE
WHEN rownumber = 1
THEN mainterm
ELSE NULL
END,scopenote,subterms,codes
)
FROM CTEterm
GROUP BY GROUPING SETS ((mainterm,rownumber),(mainterm,scopenote),subterms),codes))
ORDER BY mainterm,codes,scopenote
GO
基本上如何避免在CASE中使用\'ELSE NULL \'(例如\'else skip row \')?
这就是我用COALESCE得到的
ABC
NULL
SN abc_scopenote
NT DEF
NT GHI
CODE S01
CODE S02
NULL
DEF
SN def_scopenote
BT ABC
RT GHI
NULL
GHI
BT ABC
RT DEF
CODE B04
这就是我所需要的
ABC
SN abc_scopenote
NT DEF
NT GHI
CODE S01
CODE S02
DEF
SN def_scopenote
BT ABC
RT GHI
GHI
BT ABC
RT DEF
CODE B04
同样的问题在这里
解决方法
抱歉,如果结果不是您期望的那样,但是如果您只需要摆脱NULL,那么我看不到为什么您不能这样做:
;WITH CTEterm AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY #term.en,refterm.en
ORDER BY #term.en) AS rownumber,#term.en AS mainterm,CHAR(9) + \'SN \' + #term.enscope AS scopenote,CHAR(9) + #link.reltype + CHAR(32) + refterm.en AS subterms,CHAR(9) + \'CODE \' + #categorylink.code AS codes
FROM #link
INNER JOIN #term ON #term.termid = #link.termid
INNER JOIN #term AS refterm ON refterm.termid = #link.refid
LEFT JOIN #categorylink ON #term.termid = #categorylink.termid
)
SELECT
AggValue
FROM (
SELECT
mainterm,codes,subterms,scopenote,
COALESCE(
CASE WHEN rownumber = 1 THEN mainterm ELSE NULL END,codes
) AS AggValue
FROM CTEterm
GROUP BY GROUPING SETS ((mainterm,rownumber),(mainterm,scopenote),subterms),codes))
) s
WHERE AggValue IS NOT NULL
ORDER BY mainterm,scopenote
注意:此处删除ELSE NULL
只是因为它什么都没有改变(没有ELSE
时就暗含了NULL
),而不是因为删除它会得到任何收益。