2011-08-25 34 views
10

Cách lấy hàm sẵn có cho các giá trị cột được tách nhau bằng dấu phẩy trong sql trong DB2, ví dụ: nếu có các cột có id chính sách này và có 3 hàng có cùng id nhưng có ba vai trò khác nhau trong ba hàng, sau đó nó sẽ truy xuất các hàng trong một hàng "3,4,5"Giá trị phân cách bằng dấu phẩy của DB2

ví dụ

1. 4555 "2" 
2. 4555 "3" 
3. 4555 "4" 

đầu ra 4555 2,3,4 trong DB2 trong một hàng

Trả lời

3

Đây là chính xác những gì bạn cần:

http://radheshk.blogspot.com/2008/02/sql-tips-techniques-string-aggregation.html

Đáng buồn thay, không có cách xác định hàm tổng hợp tùy chỉnh trong DB2 dễ dàng (hoặc không mũ tôi biết). Vì vậy, người ta phải sử dụng các truy vấn đệ quy, như trong ví dụ trên.

Một cách khác để giải quyết vấn đề này liên quan đến con trỏ, nhưng điều đó có lẽ còn tồi tệ hơn ...

+0

Cảm ơn câu trả lời – gaurav

-1

Hãy thử điều này:

SELECT GROUP_CONCAT(field1, field2, field3 ,field4 SEPARATOR ', ') 
+0

gì sẽ là field1 ở đây – gaurav

+0

Trường1: 1.4555 - CHỌN GROUP_CONCAT (trường1,, trường 3, trường4 SEPARATOR ',') –

+0

Ca n bạn hãy xây dựng câu hỏi của bạn?: D –

7

Tùy thuộc vào phiên bản DB2 bạn có, bạn có thể sử dụng chức năng XML để đạt được điều này.

Ví dụ bảng với một số dữ liệu

create table myTable (id int, category int); 
insert into myTable values (1, 1); 
insert into myTable values (2, 2); 
insert into myTable values (3, 1); 
insert into myTable values (4, 2); 
insert into myTable values (5, 1); 

kết quả tổng hợp sử dụng các hàm xml

select category, 
    xmlserialize(XMLAGG(XMLELEMENT(NAME "x", id)) as varchar(1000)) as ids 
    from myTable 
    group by category; 

kết quả:

CATEGORY IDS 
-------- ------------------------ 
     1 <x>1</x><x>3</x><x>5</x> 
     2 <x>2</x><x>4</x> 

Sử dụng thay thế để làm cho kết quả tìm kiếm tốt hơn

select category, 
     replace(
     replace(
     replace(
      xmlserialize(XMLAGG(XMLELEMENT(NAME "x", id)) as varchar(1000)) 
      , '</x><x>', ',') 
      , '<x>', '') 
      , '</x>', '') as ids 
    from myTable 
    group by category; 

kết quả sạch

CATEGORY IDS 
-------- ----- 
     1 1,3,5 
     2 2,4 

Chỉ cần nhìn thấy một giải pháp tốt hơn sử dụng XMLTEXT thay vì XMLELEMENT here.

26

Hàm LISTAGG là hàm mới trong DB2 LUW 9.7

xem ví dụ:

create table myTable (id int, category int); 

insert into myTable values (1, 1); 
insert into myTable values (2, 2); 
insert into myTable values (5, 1); 
insert into myTable values (3, 1); 
insert into myTable values (4, 2); 

dụ: chọn mà không cần bất kỳ trật tự trong cột nhóm

select category, LISTAGG(id, ', ') as ids from myTable group by category; 

kết quả:

CATEGORY IDS 
--------- ----- 
1   1, 5, 3 
2   2, 4 

dụ: chọn với trật tự bởi điều khoản trong cột nhóm

select 
    category, 
    LISTAGG(id, ', ') WITHIN GROUP(ORDER BY id ASC) as ids 
from myTable 
group by category; 

kết quả:

CATEGORY IDS 
--------- ----- 
1   1, 3, 5 
2   2, 4 
7

Tôi nghĩ rằng với truy vấn nhỏ này, bạn có thể làm những gì bạn muốn. Điều này tương đương với GROUP_CONCAT của MySQL trong DB2.

SELECT 
NUM, 
SUBSTR(xmlserialize(xmlagg(xmltext(CONCAT(', ',ROLES))) as VARCHAR(1024)), 3) as ROLES 
FROM mytable 
GROUP BY NUM; 

ra một cái gì đó Điều này sẽ như:

NUM ROLES 
---- ------------- 
1  111, 333, 555 
2  222, 444 

assumming kết quả ban đầu của bạn là một cái gì đó như thế:

NUM ROLES 
---- --------- 
1  111 
2  222 
1  333 
2  444 
1  555 
0

Vấn đề của tôi là transpose lĩnh vực hàng (CLOB) đến cột (VARCHAR) với một CSV và sử dụng bảng transposed để báo cáo. Bởi vì việc chuyển đổi trên lớp báo cáo sẽ làm chậm báo cáo.

Một cách cần thực hiện là sử dụng SQL đệ quy. Bạn có thể tìm thấy nhiều bài viết về điều đó nhưng khó tiêu tốn tài nguyên của nó nếu bạn muốn tham gia tất cả các cột chuyển tiếp đệ quy của bạn.

Tôi đã tạo nhiều bảng tạm thời toàn cầu, nơi tôi đã lưu trữ các cột được chuyển đổi đơn lẻ với một mã định danh khóa. Cuối cùng, tôi đã có 6 bảng tạm thời để tham gia 6 cột nhưng do phân bổ nguồn lực hạn chế, tôi không thể mang tất cả các cột lại với nhau. Tôi đã chọn dưới 3 công thức và sau đó tôi chỉ phải chạy 1 truy vấn cho phép xuất trong 10 giây.

Tôi đã tìm thấy các bài viết khác nhau về cách sử dụng các hàm XML2CLOB và đã tìm thấy 3 cách khác nhau.

REPLACE(VARCHAR(XML2CLOB(XMLAGG(XMLELEMENT(NAME "A",ALIASNAME.ATTRIBUTENAME)))),'', ',') AS TRANSPOSED_OUTPUT 
NVL(TRIM(',' FROM REPLACE(REPLACE(REPLACE(CAST(XML2CLOB(XMLAGG(XMLELEMENT(NAME "E", ALIASNAME.ATTRIBUTENAME))) AS VARCHAR(100)),'',' '),'',','), '', 'Nothing')), 'Nothing') as TRANSPOSED_OUTPUT 
 
RTRIM(REPLACE(REPLACE(REPLACE(VARCHAR(XMLSERIALIZE(XMLAGG(XMLELEMENT(NAME "A",ALIASNAME.ATTRIBUTENAME) ORDER BY ALIASNAME.ATTRIBUTENAME) AS CLOB)), '',','),'',''),'','')) AS TRANSPOSED_OUTPUT 

Hãy chắc chắn rằng bạn đang đúc "AttributeName" của bạn để varchar trong một subquery và sau đó gọi nó ở đây.

0

khả năng khác, với CTE đệ quy

with tablewithrank as (
    select id, category, rownumber() over(partition by category order by id) as rangid , (select count(*) from myTable f2 where f1.category=f2.category) nbidbycategory 
    from myTable f1 
    ), 
    cte (id, category, rangid, nbidbycategory, rangconcat) as (
    select id, category, rangid, nbidbycategory, cast(id as varchar(500)) from tablewithrank where rangid=1 
    union all 
    select f2.id, f2.category, f2.rangid, f2.nbidbycategory, cast(f1.rangconcat as varchar(500)) || ',' || cast(f2.id as varchar(500)) from cte f1 inner join tablewithrank f2 on f1.rangid=f2.rangid -1 and f1.category=f2.category 
    ) 
    select category, rangconcat as IDS from cte 
    where rangid=nbidbycategory 
Các vấn đề liên quan