2015-07-05 5 views
1

У меня есть этот запрос:Как сгруппировать пару строк в SQL Server?

SELECT 
    Table1.ID, Table1.Code1, Table1.Code2, Table1.Details, 
    Table1.IDS, Table2.Name 
FROM 
    Table1 
INNER JOIN 
    Table2 ON Table1.Code1 = Table2.Code1 
WHERE 
    Table1.IDS = 1 
ORDER BY 
    Table1.Code1, Table1.Code2 

Это мой результат для запроса:

ID Code1 Code2 Details IDS Name 
1  1001  01  D1  1  N1 
2  1001  01  D2  1  N1 
3  1001  02  D3  1  N1 
4  1001  05  D4  1  N1 
5  1002  11  D5  1  N2 
6  1002  12  D6  1  N2 
7  1005  21  D7  1  N3 
8  1005  21  D8  1  N3 

Но я хочу этот результат:

ID Code1 Code2 Details IDS Name 
1  1001  01  D1  1  N1 
2    01  D2  1 
3    02  D3  1 
4    05  D4  1 
5  1002  11  D5  1  N2 
6    12  D6  1 
7  1005  21  D7  1  N3 
8    21  D8  1 

Как получить этот результат? Пожалуйста, помогите мне. Большое спасибо

+0

ли идентификаторы (Table1.ID) всегда в порядке, вы хотите, чтобы результаты? –

+0

№. Таблица1.ID не большое дело. Моя цель - устранение дублирования во втором столбце. Точно я хочу иметь напечатанный документ, как указано выше в C#, но я не могу создать требуемый запрос. –

ответ

0

Если вы можете положиться на столбец идентификатора для упорядочения групп (или комбинации других строк, например code1, code2), вы можете сделать это несколькими способами.

Если ваш сервер 2012+, то вы можете использовать функцию окна LAG() для доступа к предыдущим строкам, а если предыдущие строки Code1 совпадают с текущими строками Code1, замените его нулевым (или пустой строкой, если это подходит ты лучше). Однако, если вы используете версию < 2012, вы можете выполнить ее, используя самостоятельное соединение.

Этот вид форматирования может быть лучше обрабатывать на стороне клиента (или уровне отчетности), хотя, если возможно.

Запрос ниже включает в себя обе версии, но я закомментировал автообъединение материал:

SELECT 
    Table1.ID, 

    -- CASE WHEN Table1.Code1 = t1.Code1 THEN NULL ELSE Table1.Code1 END AS Code1, 
    CASE WHEN LAG(Table1.Code1) OVER (ORDER BY Table1.ID) = Table1.Code1 THEN NULL ELSE Table1.Code1 END AS Code1, 

    Table1.Code2, Table1.Details, Table1.IDS, 

    -- CASE WHEN Table1.Name = t1.Name THEN NULL ELSE Table1.Name END AS Name, 
    CASE WHEN LAG(Table2.Name) OVER (ORDER BY Table1.ID) = Table2.Name THEN NULL ELSE Table2.Name END AS Name 

FROM 
    Table1 
INNER JOIN 
    Table2 ON Table1.Code1 = Table2.Code1 
-- LEFT JOIN Table1 t1 ON Table1.ID = t1.ID + 1 
WHERE 
    Table1.IDS = 1 
ORDER BY 
    Table1.Code1, Table1.Code2 

Sample SQL Fiddle

1

Внедрение логики представления в ваш запрос не является идеальным. Я рекомендую обрабатывать результаты запроса программно, либо обнаруживать, когда группы меняются по мере повтора, либо преобразовывать результаты запроса во вложенную таблицу. Последнее можно обобщить как функцию многократного использования.

0

Morteza,

Это явный случай презентационного слоя/UI требование. Базы данных создаются для определенной цели, а именно для хрустания данных и представления результатов. Я настоятельно рекомендую вам обратиться к логике интерфейса для достижения своей цели.

0

Использование ROW_NUMBER() в CTE или subquery, вот один из способов получить ожидаемый результат:

;WITH q1 as 
(
SELECT 
    t1.ID, 
    t1.Code1, 
    t1.Code2, 
    t1.Details, 
    t1.IDS, 
    t2.Name, 
    ROW_NUMBER() OVER (PARTITION BY t1.Code1 ORDER BY t1.ID) as rn 
FROM 
    table1 t1 
INNER JOIN 
    Table2 t2 ON t1.Code1 = t2.Code1 
) 

SELECT 
    q1.ID, 
    CASE 
     WHEN rn = 1 THEN q1.Code1 
    ELSE '' 
    END as Code1, --only populate first row for each code1 
    q1.Code2, 
    q1.Details, 
    q1.IDS, 
    CASE 
     WHEN rn = 1 THEN q1.Name 
    ELSE '' 
    END as Name --only populate first row for each name 
FROM 
    q1 
WHERE 
    q1.IDS = 1 
ORDER BY 
    q1.Code1, q1.Code2 

SQL Fiddle Demo

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