2012-04-11 2 views
-1

Я получаю следующие выходные данныеСлияние общих строк в SQL

Code Manager Employee 
1  A   Emp1 
1  A   Emp2 
1  A   Emp3 
2  B   Emp4 
2  B   Emp5 

, но я хочу привести в качестве

Code Manager Employee 
1  A   Emp1 
        Emp2 
        Emp3 
2  B   Emp4 
        Emp5 

кода и менеджер столбцы не должны repeat.It должен быть пустым.

+0

Я думаю, вы не можете сделать это с помощью запроса ... – Marco

+0

Вы действительно уверены, что это имеет смысл? пожалуйста, объясните свой контекст/почему вы это делаете – VAShhh

+1

Если оставить столбцы пустыми, как вы можете сказать, что 'Emp2' для' Code = 1' и 'Manager = A'? –

ответ

2
select case when Code = lag(Code) over(order by Code, Manager, Employee) 
     then null 
     else Code 
     end as Code, 
     case when Manager = lag(Manager) over(order by Code, Manager, Employee) 
     then null 
     else Manager 
     end as Manager, 
     Employee 
from YourTable Y 
order by Y.Code, Y.Manager, Y.Employee 

Примерить SQL Fiddle

0

Это невозможно по SQL. Вы должны вручную закодировать данные в коде после получения его из базы данных.

Редактировать

После комментариев Vashh и Ливен, я понял, что это возможно. Поэтому, если он нужен для показа, он может либо использовать Func (предложенный Vaassh), Join with null (s. By Lieven), либо может быть циклом и добавить к datagridview или таблице или тому, что он хочет использовать.

+0

Вы можете сделать это с помощью функции transact-sql, но кажется логически неправильной – VAShhh

+1

Возможно, но не очень. Это предполагает объединение с самим собой и использование case case для определения того, должен ли код и менеджер выводить свои значения или просто NULL. –

+0

Да, я полностью забыл об этом. Я думаю, что если он хочет только для лучшей демонстрации, он может выбрать func или join, как вы предложили вам, ребята. – Marshal

1

Для выполнения такого рода форматирования вам нужно что-то вроде Access или Crystal Reports. Его невозможно в простом SQL.

0

Для удовольствия, следуя один из способов сделать это, но в конце концов, это лучше сделать в приложении конечного пользователя

;WITH YourTable (Code, Manager, Employee) AS(
    SELECT * FROM (VALUES 
     (1, 'A', 'Emp1') 
     , (1, 'A', 'Emp2') 
     , (1, 'A', 'Emp3') 
     , (2, 'B', 'Emp4') 
     , (2, 'B', 'Emp5') 
    ) a (b, c, d)  
) 
, q AS (
    SELECT rn = ROW_NUMBER() OVER (ORDER BY Code, Manager, Employee), * 
    FROM YourTable 
) 
SELECT Code = CASE WHEN q1.Code = q2.Code THEN NULL ELSE q1.Code END 
     , Manager = CASE WHEN q1.Code = q2.Code THEN NULL ELSE q1.Manager END 
     , q1.Employee 
FROM q q1 
     LEFT OUTER JOIN q q2 ON q1.rn = q2.rn + 1 
0

Я знаю, что вы просите ответ в Oracle , но, возможно, этот пример SQL Server поможет вам (если вы действительно, действительно нужно сделать это так, а не в среде отчетности):

DECLARE @TBL TABLE(
    Code  INT, 
    Manager CHAR(1), 
    Employee VARCHAR(4)) 

INSERT @TBL VALUES (1,'A','Emp1') 
INSERT @TBL VALUES (1,'A','Emp2') 
INSERT @TBL VALUES (1,'A','Emp3') 
INSERT @TBL VALUES (2,'B','Emp4') 
INSERT @TBL VALUES (2,'B','Emp5') 

;WITH cte 
    AS (SELECT Code 
       ,Manager 
       ,Employee 
       ,ROW_NUMBER() OVER(ORDER BY Code) rownum 
     FROM @TBL) 
SELECT CASE curr.Code 
     WHEN prev.Code THEN '' 
     ELSE CAST(curr.Code AS VARCHAR(20)) 
     END AS _Code 
     ,CASE curr.Manager 
      WHEN prev.Manager THEN '' 
      ELSE curr.Manager 
     END AS _Manager 
     ,curr.Employee 
FROM cte curr 
     LEFT JOIN cte prev 
     ON curr.rownum = prev.rownum + 1 
0

Если вы используете только SQL Server 2005/2008, вам может достичь этого следующим образом.

declare @table table (
Code int, 
Manager Varchar(1), 
Employee varchar(10) 
) 

insert into @table values 
(1,'A','Emp1'), 
(1,'A','Emp2'), 
(1,'A','Emp3'), 
(2,'A','Emp4'), 
(2,'A','Emp5') 

select * from @table 
select 
case when number=1 then Code else null end as Code, 
case when number=1 then Manager else null end as Manager, 
employee 
from (
select *, 
row_number() over (partition by code, manager order by code,manager) as number 
from @table 
) x 

Который даст вам:

(5 row(s) affected) 
Code  Manager Employee 
----------- ------- ---------- 
1   A  Emp1 
1   A  Emp2 
1   A  Emp3 
2   A  Emp4 
2   A  Emp5 

(5 row(s) affected) 

Code  Manager employee 
----------- ------- ---------- 
1   A  Emp1 
NULL  NULL Emp2 
NULL  NULL Emp3 
2   A  Emp4 
NULL  NULL Emp5 

(5 row(s) affected) 
+0

Не видел тег Oracle :-( – Maarten

0

Готово :)

Вы можете изменить NULL значения в '', если вы хотите.

WITH 
CTE1 AS (
SELECT DISTINCT [Code], [Manager], 
( SELECT TOP 1 Employee 
    FROM [dbo].[table] t2 
    WHERE t1.Code = t2.Code AND t1.Manager = t2.Manager 
    ORDER BY Employee) AS [Employee] 
FROM [dbo].[table] t1) 
, 
CTE2 AS (
     SELECT * FROM [dbo].[table] 
     EXCEPT 
     SELECT * FROM CTE1) 

SELECT * FROM CTE1 
UNION 
SELECT NULL as Code, NULL as Manager, Employee 
FROM CTE2 
ORDER BY Employee 
0

My SQL * Plus немного ржавый, но если это тот инструмент, который вы используете, то он должен быть достаточно простым, но с помощью команды BREAK.

Как уже упоминалось в одном из комментариев, это лучше всего оставить на вашем инструменте отчетности, чем в реальном SQL, потому что отдельная строка без всех значений не имеет никакого смысла вне контекста набора результатов.

BREAK on code on manager 

SELECT code, manager, employee 
FROM yourTable y 
order by code, manager; 

Пожалуйста, не то, что мой SQL * Plus немного ржавый, так что это может не работать точно, но детали команды BREAK можно найти in the Oracle documentation.

Смежные вопросы