我尝试合并同一个表的两行,而每行都有一个优先级。 感兴趣的值是优先级为1的值,如果它不是NULL;否则优先级为0的值。
示例数据源可以是:
| Id | GroupId | Priority | Col1 | Col2 | Col3 | ... | Coln |
-----------------------------------------------------------------
| 1 | 1 | 0 | NULL | 4711 | 3.41 | ... | f00 |
| 2 | 1 | 1 | NULL | NULL | 2.83 | ... | bar |
| 3 | 2 | 0 | NULL | 4711 | 3.41 | ... | f00 |
| 4 | 2 | 1 | 23 | NULL | 2.83 | ... | NULL |
我希望:
| GroupId | Col1 | Col2 | Col3 | ... | Coln |
-------------------------------------------------
| 1 | NULL | 4711 | 2.83 | ... | bar |
| 2 | 23 | 4711 | 2.83 | ... | f00 |
TSQL中是否存在通用方法而无需明确检查每一列?
SELECT
t1.GroupId,
ISNULL(t2.Col1, t1.Col1) as Col1,
ISNULL(t2.Col2, t1.Col2) as Col2,
ISNULL(t2.Col3, t1.Col3) as Col3,
...
ISNULL(t2.Coln, t1.Coln) as Coln
FROM mytable t1
JOIN mytable t2 ON t1.GroupId = t2.GroupId
WHERE
t1.Priority = 0 AND
t2.Priority = 1
此致
答案 0 :(得分:0)
我认为如果不为每列使用isnull,这将会满足您的要求
select
*
from
mytable t1
where
priority=(select max(priority) from mytable where groupid=t1.groupid group by groupid)
答案 1 :(得分:0)
我将详细阐述@KM建议的ROW_NUMBER()解决方案,因为IMO是最好的解决方案。 (以CTE形式,以便于阅读)
WITH cte AS (
SELECT
t1.GroupId,
t1.Col1,
t1.Col2,
ROW_NUMBER() OVER(PARTITION BY t1.GroupId ORDER BY ISNULL(GroupId ,-1) ) AS [row_id]
FROM
mytable t1
)
SELECT
*
FROM
cte
WHERE
row_id = 1
这将为mytable中的每个GroupId提供具有最高优先级的行(根据您的规则)。
ROW_NUMBER和RANK是我最喜欢的两个TSQL技巧。 http://msdn.microsoft.com/en-us/library/ms186734.aspx
编辑:我的另一个最喜欢的是PIVOT / UNPIVOT,您可以使用它来转置行/列,这是解决此类问题的另一种方式。 http://msdn.microsoft.com/en-us/library/ms177410.aspx