程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL 語句中一條常見的行合並問題

SQL 語句中一條常見的行合並問題

編輯:關於SqlServer


  問題:原來問題:現有兩個表:

  表一originalWord

  ID Word

  --------------

  101 about

  102 abound

  103 beard

  104 boast

  105 beast

  表二similarWord

  ID original_id similar_id

  -------------------------------

  1 101 102

  2 102 101

  3 103 105

  4 105 103

  5 104 105

  6 105 104

  表originalword和表similarWord有關系:

  表similarword的original_id是表originalWord中的ID

  表similarword的similar_id也是表originalWord中的ID

  第一個表是一個單詞表,是源單詞

  第二個表是由第一個表來的,是形近詞的id列表

  如表一中的101和102是形近詞,則在第二個表中我插入了(101,102)和(102,101)兩個記錄

  103和104分別和105是形近詞,則在第二個表中我插入了(103,105)、(105,103)、(104,105)、(105,104)四個記錄

  想查詢出如下的結果:

  結果表

originalword.ID       orig_word       similar_Word
-------------------------------------------
101                               about               abound
102                               abound             about
103                               beard               beast
104                               boast               beast
105                               beast               beard,   boast


  請大家幫忙啊,寫個查詢語句,急!謝謝先!

  回答:

  這樣的問題一般寫個自定義函數,由orig_word 統計similar_Word,就可以實現。

  來自一朋友叫hxd001_810,使用自定義函數的方法:

  用函數解決之。代碼如下:

--創建一個合並的函數
create function f_hb(@original_id varchar(10))
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' +b.Word
        from similarword a inner join dbo.originalWord b on a.similar_id=b.ID
        where original_id = @original_id
set @str = right(@str , len(@str) - 1)
return(@str)
End
go
--調用自定義函數得到結果:
select distinct a.original_id [originalword.ID],b.word [orig_Word],dbo.f_hb(a.original_id) as similar_id
from similarword a inner join dbo.originalWord b on a.original_id=b.ID
go
返回:
originalword.ID orig_Word      similar_id
--------------- ------------- -----------
101             about          abound
102             abound         about
103             beard          beast
104             boast          beast
105             beast          beard,boast
 


  (所影響的行數為 5 行)

  從性能分析,個人認為使用自定義函數性能比使用循環語句效率低一點,特別是在處理大量數據時候。

  以下是自己寫的一個使用循環的方法: 

SET NOCOUNT ON
CREATE TABLE originalword(id int ,Word nvarchar(30))
CREATE TABLE similarWord (ID int ,original_id int,similar_id int)
GO
INSERT INTO originalWord
SELECT 101,     'about' UNION ALL
SELECT 102,     'abound' UNION ALL
SELECT 103,     'beard' UNION ALL
SELECT 104,     'boast' UNION ALL
SELECT 105,     'beast'
INSERT INTO similarWord
SELECT 1,         101,                         102  UNION ALL
SELECT 2,         102,                         101  UNION ALL
SELECT 3,         103,                         105  UNION ALL
SELECT 4,         105,                         103  UNION ALL
SELECT 5,         104,                         105  UNION ALL
SELECT 6,         105,                         104
GO

DECLARE @Result TABLE(id int IDENTITY(1,1),[originalword.ID] int,orig_word nvarchar(30),similar_Word nvarchar(30))
INSERT INTO @Result ([originalword.ID],orig_word) SELECT * FROM originalWord
DECLARE @i int
        ,@j int
        ,@similar_Word nvarchar(200)

SELECT @i=1,@j=ISNULL(COUNT(1),0) FROM @Result
WHILE @i<=@j
        BEGIN
                SET @similar_Word=''
                SELECT @similar_word=@similar_word+Word+',' FROM
                        (SELECT B.word FROM similarword A INNER JOIN originalWord B ON A.original_id=B.ID
                                AND EXISTS(SELECT 1 FROM @Result C WHERE C.[originalWord.ID]=A.original_id AND C.ID=@i)) Tmp
                IF(ISNULL(@similar_Word,'')<>'')
                        UPDATE @Result SET similar_word=SUBSTRING(@similar_word,1,LEN(@similar_Word)-1) WHERE ID=@i
                SET @i=@i+1
        END
SELECT [originalword.ID],orig_word,similar_Word FROM @Result

GO
DROP TABLE  originalword,similarWord
GO
 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved