表格Family就像
No. ADD Member Det1 Det2 Det3 Det4
1 Add1 Dad1 q w e r
1 Add1 Mom1 q w e r
1 Add1 Chd1 q w e r
1 Add1 Chd1 q w e r
1 Add2 Mom2 q w e r
1 Add2 Chd2 q w e r
1 Add2 Chd2 q w e r
这里的ADD 就像每个家庭唯一的家庭ID一样,会员是会员姓名,家庭可以有任意号码。
期望的输出:
No. ADD Member Det1 Det2 Det3 Det4 Member Det1 Det2 Det3 Det4 .. more
1 Add1 Dad1 q w e r Mom1 q w e r .. more
2 Add2 Mom2 q w e r Chd1 q w e r .. more
我尝试为成员数量
创建别名SELECT a.ADD
,a.Member
,a.Det1
,a.Det2
,a.Det3
,a.Det4
,b.bDD
,b.Member
,b.Det1
,b.Det2
,b.Det3
,b.Det4
FROM Family a
,Family b
WHERE a.ADD = b.ADD
答案 0 :(得分:0)
编辑:太平洋标准时间11:26我认为你需要动态SQL来做你想做的事情。当您正在执行一个复杂的块集时,您将逐列添加并重复列名称。
declare @Temp table ( [No] int, [Add] varchar(4), Member varchar(4), Det1 char, Det2 char, Det3 char, Det4 char);
insert into @Temp values
(1, 'Add1', 'Dad1', 'q','w','e','r'),
(1, 'Add1', 'Mom1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add2', 'Mom2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r')
if object_id('tempdb..#Temp') is not null
drop table #temp
select
No
, [Add]
, Member
, Det1
, Det2
, Det3
, Det4
, dense_rank() over(order by [Add]) as part
, row_number() over(partition by [Add] order by Member) as rwn
into #Temp
from @Temp
declare
@Cursor int = 1
, @Max int
, @Addendum varchar(max) = ''
, @NL char = char(10)
, @SQL nvarchar(max)
, @Part int
;
-- set up my loop prep
-- statement to execute later
select @SQL = 'Select No, [Add] ' + @NL + 'from #Temp' + @NL + 'group by No, [Add]';
-- max iteration of an occurence
Select @Max = max(rwn) from #Temp
-- ensure we use the part that has the max occurrence, less we get less results than we need
Select @Part = max(part) from #Temp where rwn = @Max
-- While the statement is looping it is adding to itself dynamically to select your values. I could do a loop of a loop
-- to get only certain values you want too, but this is enough for an example. EG, set a bit for Det1, Det2 and then make a statement for those things too.
While @Cursor <= @Max
BEGIN
Select @Addendum += @NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Member end) as Member ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det1 end) as Det1 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det2 end) as Det2 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det3 end) as Det3 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det4 end) as Det4 '
from #Temp where part = @Part and rwn = @Cursor
Select @Cursor += 1;
END
-- 'stuff' is a sql syntax to insert in a specific place a chunk of something.
Select @SQL = stuff(@SQL, charindex('from', @SQL), 0, @Addendum + @NL);
-- I want to now 'execute' the statement I just built up in memory to select what I need
exec sp_executesql @SQL
看起来你只是在做一个复杂的分组,但我不确定你的例子,如果你想要明确地遗漏你的一些成员。这将按原样在SQL Server 2008及更高版本上运行:
declare @Temp table ( [No] int, [Add] varchar(4), Member varchar(4), Det1 char, Det2 char, Det3 char, Det4 char);
insert into @Temp values
(1, 'Add1', 'Dad1', 'q','w','e','r'),
(1, 'Add1', 'Mom1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add2', 'Mom2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r')
Select *
from @Temp
select
No
, [Add]
, Member
, max(Det1) as Det1
, max(Det2) as Det2
, max(Det3) as Det3
, max(Det4) as Det4
from @Temp
group by No, [Add], Member
A&#39; Pivot&#39;程序适用于获取一组通常与单一类型相关联的值。值。这适用于查找值为多行的事物。
就像你有一个人,他们被链接到一个订单表,订单表有一个类型列与查找表相关,查找表是一个密钥对表,如
1 =衬衫,2 =裤子,3 =鞋子,4 =袜子,5 =腰带,6 =帽子,7 =手表等。
你可以通过简单的左连接和表达&#39;类型&#39;来为一些事情做一个转移。你想要转移。 EG:
from person p
left join order o1 on p.personid = o1.personid and o1.type = 1
left join order o2 on p.personid = o2.personid and o2.type = 2
引擎中没有规则表明你只能加入一次表,所以如果我指定你加入关系并特别是某种类型,我可以像这样评估我的选择:
Select p.PersonName, o1.Value, o2.Value
通常情况下,如果您拥有一大堆类型并且您不想进行多个左连接,则会使用Pivot。当你做一组你想要分组的序列时,你真的只需要做一个&#39;组。对于简单的集合。我可以通过以下方式做到这一点:
在下面的表达式中为我做分组的最大值(case then then then end)语句:
选择 y.PersonName ,max(OrderID = 1然后OrderAmount结束的情况) ,max(OrderID = 2然后OrderAmount结束的情况) ,max(OrderID = 3然后OrderAmount结束的情况) 来自@Person y 在x.PersonId = y.PersonId上加入@Orders x 按人名分组
窗口函数可以为我提供动态分组功能,而不需要&#39;组。子句。
选择 y.PersonName , 订单金额 ,row_number()over(按OrderName的PersonName顺序分区)orderbyAmount ,row_number()over(由OrderAmount desc按PersonName顺序分区)orderbyAmountDesc ,max(OrderID = 1然后OrderAmount结束时的情况)over(按PersonName分区)
,max(OrderID = 2然后OrderAmount结束时的情况)over(按PersonName分区) ,max(OrderID = 3然后OrderAmount结束时的情况)over(按PersonName分区) 来自@Person y 加入@Orders x on x.PersonId = y.PersonId
如果有人想要一些疯狂的报告,列出第二次或最后一次出现的复杂过程,这给了我灵活性。