web-dev-qa-db-ja.com

T-SQLのGROUP BYに含めることなく、SELECT部分​​にBIT型の列を含める方法

これが私のT-SQLクエリです

_SELECT 
    ProductID,
    VendorID,
    ProductName= MAX(ProductName),
    VendorName = MAX(VendorName),
    IsActive = MAX(IsActive) # This brings error 
FROM ProductVendorAssoc 
GROUP BY  
    ProductID,
    VendorID
_

_GROUP BY_フィールドにのみ_ProductID and VendorID_を適用したいのですが、_ProductID, VendorID, ProductName, VendorName, IsActive_フィールドに入力する必要があります。

ここでは、集約関数MAX(ProductName)を使用して、group by listでProductNameを回避しました。

ただし、オペランドデータ型ビットがmax演算子に対して無効であるため、BIT列に対して同じトリックは機能しません。

_GROUP BY_に含めずにBITT部分にSELECタイプの列を含めるにはどうすればよいですか?

更新

同じようにINTUserIDのようなSELECT列を含める必要がある場合はどうすればよいですか

51

そこにCASE式を入れるか、intに変換します:

IsActive = MAX(CASE WHEN IsActive=1 THEN 1 ELSE 0 END)

または、

IsActive = MAX(CONVERT(int,IsActive))

また、結果セットのProductName、VendorNameおよびIsActive列の値はすべて、ベーステーブルの異なる行から取得される可能性があることを意味することも明らかです。


これらの3つの列を実際にはすべて同じ行から取得する場合(およびSQL Server 2005以降を想定)、次のようにします。

;With Numbered as (
    SELECT *,ROW_NUMBER() OVER (
        PARTITION BY ProductID,VendorID
        ORDER BY /* Something appropriate, or if we just want random... */ newid()) as rn
    FROM ProductVendorAssoc
)
select
    ProductID,
    VendorID,
    ProductName,
    VendorName,
    IsActive
FROM Numbered where rn=1
88

これを行うより短い方法:

IsActive = MAX(0+IsActive)
10
Mike Keskinov

SQL2005/2008では、これは次のようになります。

select ProductId, VendorId, ProductName, VendorName, IsActive
from
(
    select *, row_number() over (partition by ProductId, VendorId order by ProductId) RowNumber
    from Production.Product
) tt
where RowNumber = 1
3
Alex Aza