2016-03-16 36 views
5

Tôi có chế độ xem sql, hãy gọi nó là SampleView, có kết quả có định dạng sau.nhóm tsql bằng cách lấy giá trị cột chữ và số với độ dài tối đa

Id (INT), NameA (VARVHAR(50)), NameB (VARCHAR(50)), ValueA (INT), ValueB (INT) 

Tập kết quả của chế độ xem có chứa các hàng có thể giống nhau Id hay không. Khi có hai hoặc nhiều hàng với Id cùng, tôi muốn để có được một cái gì đó như sau

SELECT 
    Id, 
    MAX(NameA), 
    MAX(NameB), 
    MAX(ValueA), 
    MAX(ValueB) 
FROM SampleView 
GROUP BY Id 
ORDER BY Id 

Về cột Id, ValueAValueB không có bất kỳ vấn đề. Mặt khác, sử dụng MAX cho cả hai NameANameB mọi thứ không như mong muốn. Sau khi một số googling và tìm kiếm tôi nhận ra rằng MAX đã không phải là "mong đợi" hành vi cho các cột chữ số. Nói dự kiến, ý tôi là sử dụng MAX trong trường hợp của tôi, nó sẽ trả về giá trị NameA với số ký tự tối đa, MAX(LEN(NameA)). Tôi phải đề cập đến ở đây rằng không có khả năng cho NameA để có hai giá trị cho cùng một Id với cùng độ dài. Điều này có thể làm cho vấn đề dễ giải quyết hơn.

Tôi sử dụng SQL Server 2012 và TSQL.

Bạn có đề xuất nào về cách tôi có thể giải quyết vấn đề này không?

Cảm ơn bạn rất nhiều vì đã giúp đỡ.

Trả lời

2

Bạn có thể sử dụng chức năng cửa sổ:

SELECT DISTINCT 
     id, 
     FIRST_VALUE(NameA) OVER (PARTITION BY id 
           ORDER BY len(NameA) DESC) AS MaxNameA, 
     MAX(ValueA) OVER (PARTITION BY id) AS MaxValueA, 
     FIRST_VALUE(NameB) OVER (PARTITION BY id 
           ORDER BY len(NameB) DESC) AS MaxNameB, 
     MAX(ValueB) OVER (PARTITION BY id) AS MaxValueB  
FROM SampleView 

Demo here

+0

Cảm ơn bạn rất nhiều! Đó là điều tôi muốn :) – Christos

2

Bạn có thể sử dụng các truy vấn tương quan như thế này:

SELECT 
    t.Id, 
    (SELECT TOP 1 s.NameA FROM SampleView s 
    WHERE s.id = t.id 
    ORDER BY length(s.NameA) DESC) as NameA, 
    (SELECT TOP 1 s.NameB FROM SampleView s 
    WHERE s.id = t.id 
    ORDER BY length(s.NameB) DESC) as NameB, 
    MAX(t.ValueA), 
    MAX(t.ValueB) 
FROM SampleView t 
GROUP BY t.Id 
ORDER BY t.Id 
+0

Tệ của tôi, tôi nên nói rằng tôi không muốn nó là một truy vấn tương quan. Tuy nhiên, kể từ khi câu trả lời của bạn là chính xác (+1) từ tôi :) – Christos

0

Một biến thể có thể là sử dụng ROW_NUMBER hai lần:

WITH 
CTE_NameA 
AS 
(
    SELECT 
     Id, 
     NameA, 
     ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LEN(NameA) DESC) AS rnA 
    FROM SampleView 
) 
,CTE_NameB 
AS 
(
    SELECT 
     Id, 
     NameB, 
     ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LEN(NameB) DESC) AS rnB 
    FROM SampleView 
) 
SELECT 
    Id, 
    CTE_NameA.NameA, 
    CTE_NameB.NameB, 
    MAX(ValueA), 
    MAX(ValueB) 
FROM 
    SampleView 
    INNER JOIN CTE_NameA ON CTE_NameA.Id = SampleView.Id AND CTE_NameA.rnA = 1 
    INNER JOIN CTE_NameB ON CTE_NameB.Id = SampleView.Id AND CTE_NameB.rnB = 1 
GROUP BY Id 
ORDER BY Id; 
+1

Thats có vẻ như nhiều: S – sagi

Các vấn đề liên quan