SQLテーブル垂直方向と水平方向の膨張

まず、垂直方向と水平方向のテーブルの実現は、百度、多くは、負担はありません。我々が思い出すように、私は絵を入れます

     

 

需要があります。例えば、輸出のユーザーのアドレス帳の場合は、エクスポートするユーザー名、住所1、住所2、住所3が必要です 

しかし、私たちのデータシートは、多くの場合、そのように設計されています

ユーザーからのuをu.UserName、u.Addressを選択

この時、私たちの輸出は、もしそうであれば結果

過去の実施は、データベースを読み取り、その後、結果セットを横断する、わずかにコードします

SQLクエリ結果が直接設定した場合(下図のように)私が欲しいです

それから私は、プログラムを通過する必要はありません。

レビューの下では、最初のビューで、テーブルは対象を特定の成果があり、case文に垂直クロステーブルコア文を回し、

ケースということを、アドレス帳は、その後、手がアドレス帳に1を追加し、SQL文を書き、それはまた、ID列を必要としないが、これは識別するのに複数のアドレスの最初のものです

コードはシンプルです

U AS dbo.Users FROM AddressIndexとして(u.UserName DESCによってu.UserName順序によってパーティション)上u.UserName、u.Address、ROW_NUMBER()を選択し

このように、我々は、データ変換テーブルの基本的な側面を出てきました。

コードが短い見え従うために、私は、CTEの声明の中で上記のステートメントを置くことにしました

(newusersのAS WITH
  U AS dbo.Users FROM AddressIndexとしてu.UserName DESCによってu.UserName順序によって(パーティション上u.UserName、u.Address、ROW_NUMBER()を選択し)

 テストCTEステートメントを実行します

WITH newUsers AS (
  SELECT u.UserName, u.Address, ROW_NUMBER() over(partition by u.UserName order by u.UserName desc) as AddressIndex FROM dbo.Users AS u
)
SELECT * FROM newUsers

和没放在cte里的执行结果一致.

 

这时候再来写表转换

WITH newUsers AS (
  SELECT u.UserName, u.Address, ROW_NUMBER() over(partition by u.UserName order by u.UserName desc) as AddressIndex FROM dbo.Users AS u
)
SELECT a.UserName,
(CASE WHEN ( a.AddressIndex =1 ) THEN a.Address ELSE null END) as extAddress1,
(CASE WHEN ( a.AddressIndex =2 ) THEN a.Address ELSE null END) as extAddress2,
(CASE WHEN ( a.AddressIndex =3 ) THEN a.Address ELSE null END) as extAddress3
from newUsers a
GROUP BY a.UserName,a.AddressIndex,a.Address

 

发现大致样子出来了. ,但是1,2,3行应该合并起来

解决方法,给上面结果集嵌套一层,代码如下

WITH newUsers AS (
SELECT u.UserName, u.Address, ROW_NUMBER() over(partition by u.UserName order by u.UserName desc) as AddressIndex FROM dbo.Users AS u
)
SELECT aa.UserName, MAX(aa.extAddress1), MAX(aa.extAddress2), MAX(aa.extAddress3)
FROM (
SELECT a.UserName,
(CASE WHEN ( a.AddressIndex =1 ) THEN a.Address ELSE null END) as extAddress1,
(CASE WHEN ( a.AddressIndex =2 ) THEN a.Address ELSE null END) as extAddress2,
(CASE WHEN ( a.AddressIndex =3 ) THEN a.Address ELSE null END) as extAddress3
from newUsers a
GROUP BY a.UserName,a.AddressIndex,a.Address
) aa GROUP BY aa.UserName 

这样就出现了想要的结果集.

或许你会说,当地址簿有4个,5个或更多的地址的时候,sql修改起来麻烦,  但是我想说,代码根据业务逻辑来.这只是一个变化点,我满足当下需求,快速上线项目, 这个代码够用已经可以了.

当然你还可以用变量来解决sql语句的生成, 但是 这样一来代码就多了 ,具体代码实现我想小伙伴们花些时间就解决了.我在这里就不贴出代码, 给个友情提示把. 如果你要修改上面的代码,用变量实现, 此时CTE语句不能用,因为cte语句后面要紧跟select 语句 而不是 exec(sql变量) .

最后一点,关于这个sql的运行效率我没测试, 有心的小伙伴可以帮我留言.

 

 

 

 

 

 

   

 

おすすめ

転載: www.cnblogs.com/geliang/p/10962809.html