我看到很多类似的问题,但是几乎所有问题都将结果分组为列名(基于结果的列名),我的是一个更简单的列表。我不在乎它是否使用动态SQL(我认为必须这样做)。
请不要告诉我需要对表格进行重组,我是在遗留系统中工作而没有选择。
基本上,我只需要一张有效表格的列表" B"与表#34; A"中的给定记录匹配的条目。
我还没有任何代码示例,因为我没有找到正确设置的方法。
Table: Customer c CustID Name 1 Bill Smith 2 Jim Jones 3 Mary Adams 4 Wendy Williams Table: Debt d CustID Creditor Balance 1 ABC Loans 245 1 Citibank 815 2 Soprano Financial 74000 3 Citibank 24 3 Soprano Financial 93000 3 Wells Fargo 275 3 Midwestern S&L 2500 4 ABC Loans 1500 4 Fred's Payday Loan 1000 Desired Output: Name Cred1 Bal1 Cred2 Bal2 Cred3 Bal3 Cred4 Bal4 Bill Smith ABC Loans 245 Citibank 815 (NULL) (NULL) (NULL) (NULL) Jim Jones Soprano Financial 74000 (NULL) (NULL) (NULL) (NULL) (NULL) (NULL) Mary Adams Citibank 24 Soprano Finanacial 93000 Wells Fargo 275 Midwestern S&L 2500 Wendy Williams ABC Loans 1500 Fred's Payday Loan 1000 (NULL) (NULL) (NULL) (NULL)
基本上,我可能必须收集某些特定" CustomerID"的大量记录的计数,并根据它来定义输出列。如果已经回答了这个问题,请随时链接并关闭它,我在搜索时没有看到这种特定情况。
答案 0 :(得分:3)
这是另一种动态方法。我们使用Row_Number()创建最小数量的列。
示例
Declare @SQL varchar(max) = Stuff((Select Distinct ','+QuoteName(concat('Cred',ColNr))
+','+QuoteName(concat('Bal',ColNr))
From (Select ColNr=Row_Number() over (Partition By CustID Order By Creditor) From Debt ) A
Order By 1
For XML Path('')),1,1,'')
Select @SQL = '
Select *
From (
Select C.Name
,B.*
From (
Select *,ColNr=Row_Number() over (Partition By CustID Order By Creditor)
From Debt
) A
Cross Apply (values (concat(''Cred'',ColNr),[Creditor])
,(concat(''Bal'' ,ColNr) ,cast(Balance as varchar(25)))
) B (Item,Value)
Join Customer C on A.CustID=C.CustID
) A
Pivot (max([Value]) For [Item] in (' + @SQL + ') ) p'
--Print @SQL
Exec(@SQL);
<强>返回
如果是Helps,则生成的SQL看起来像这样:
Select *
From (
Select C.Name
,B.*
From (
Select *,ColNr=Row_Number() over (Partition By CustID Order By Creditor)
From Debt
) A
Cross Apply (values (concat('Cred',ColNr),[Creditor])
,(concat('Bal' ,ColNr) ,cast(Balance as varchar(25)))
) B (Item,Value)
Join Customer C on A.CustID=C.CustID
) A
Pivot (max([Value]) For [Item] in ([Cred1],[Bal1],[Cred2],[Bal2],[Cred3],[Bal3],[Cred4],[Bal4]) ) p
仅针对可视化,“提供”数据透视的查询生成:
答案 1 :(得分:2)
我猜您已经知道如何使用交叉表,因此您只需准备好数据即可使用它。
第1步:加入两个表:
SELECT c.Name, d.Creditor, d.Balance
FROM Customer c
JOIN Debt d
ON c.CustID = d.CustID
第2步:在与您将用于跨选项卡的客户相关的每个元素中包含行号
SELECT c.Name, d.Creditor, d.Balance,
ROW_NUMBER() over (PARTITION BY Name ORDER BY creditor) as rndebt_tab
FROM Customer c
JOIN Debt d
ON c.CustID = d.CustID
现在你有:
CustID Creditor Balance rn
1 ABC Loans 245 1
1 Citibank 815 2
2 Soprano Financial 74000 1
3 Citibank 24 1
3 Soprano Financial 93000 2
3 Wells Fargo 275 3
3 Midwestern S&L 2500 4
4 ABC Loans 1500 1
4 Fred's Payday Loan 1000 2
第3步:为交叉表创建SOURCE
WITH cte as (
<query from step2>
)
SELECT Name,
'CREDITOR_' + RIGHT('000' + CAST(rn AS VARCHAR(3)),3) as cross_tab,
Creditor as Value
FROM cte
UNION all
SELECT Name,
'DEBT_' + RIGHT('000' + CAST(rn AS VARCHAR(3)),3) as cross_tab,
CAST(Balance as VARCHAR(max)) as Value
FROM cte
现在你有:
CustID cross_tab Value
1 CREDITOR_001 ABC Loans
1 CREDITOR_002 Citibank
2 CREDITOR_001 Soprano Financial
3 CREDITOR_001 Citibank
3 CREDITOR_002 Soprano Financial
3 CREDITOR_003 Wells Fargo
3 CREDITOR_004 Midwestern S&L
4 CREDITOR_001 ABC Loans
4 CREDITOR_002 Fred's Payday Loan
1 DEBT_001 245
1 DEBT_002 815
2 DEBT_001 ` 74000
3 DEBT_001 24
3 DEBT_002 93000
3 DEBT_003 275
3 DEBT_004 2500
4 DEBT_001 1500
4 DEBT_002 1000
编辑:我在示例中使用CustID
而不是Name
,但现在懒得改变。