尝试在sql server中创建父子层次结构

时间:2017-07-05 13:05:04

标签: sql-server

我有一个按帐户键排序的数据集。当来到某些具有NULL作为组密钥的行时,它应该将当前帐户密钥添加为所有上述行的父键,这些行具有NULL作为父键。因此,当使用null作为组键来到下一行时,您可以将当前帐户密钥设置为上面具有父键(如null)的所有行的父键。

我曾尝试将下面的数据集复制为标记下表,但正如您所见,我不能说我成功得很好,但我希望你们中的一些人可以帮助使用t-sql语法来创建父子层次结构这个

| AccountKey | ParentKey | GroupKey | AccountNumber | Cat      | LineName                     | LineId                               |
|------------|-----------|----------|---------------|----------|------------------------------|--------------------------------------|
| 1          | NULL      | 7        | 3040          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 2          | NULL      | 7        | 3041          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 3          | NULL      | 7        | 3081          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 4          | NULL      | 7        | 3082          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 5          | NULL      | 7        | 3083          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 6          | NULL      | 7        | 3085          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 7          | NULL      | 7        | 3086          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 8          | NULL      | 7        | 3087          | Account  | Salg fisk                    | C6BCDFB2-1AAC-4D05-94F1-879CDC615D76 |
| 9          | NULL      | 2        | 3000          | Account  | Salg annet                   | 26AC86B2-0667-463E-B994-11A5C6D519A6 |
| 10         | NULL      | 2        | 3010          | Account  | Salg annet                   | 26AC86B2-0667-463E-B994-11A5C6D519A6 |
| 11         | NULL      | 2        | 3020          | Account  | Salg annet                   | 26AC86B2-0667-463E-B994-11A5C6D519A6 |
| 12         | NULL      | 2        | 3030          | Account  | Salg annet                   | 26AC86B2-0667-463E-B994-11A5C6D519A6 |
| 41         | NULL      | 11       | 3050          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 42         | NULL      | 11       | 3600          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 43         | NULL      | 11       | 3601          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 44         | NULL      | 11       | 3610          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 45         | NULL      | 11       | 3615          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 46         | NULL      | 11       | 3690          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 47         | NULL      | 11       | 3691          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 48         | NULL      | 11       | 3701          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 49         | NULL      | 11       | 3705          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 50         | NULL      | 11       | 3720          | Account  | Andre driftsinntekter        | 65FFB620-AE42-4BE5-A6E7-BF3339AA04DF |
| 67         | NULL      | NULL     | NULL          | SubTotal | Sum inntekter                | NULL                                 |
| 68         | NULL      | 13       | 4120          | Account  | Innkjøp smolt/settefisk/rogn | F9EE1CE4-22C7-400B-BC9D-E2D3214A5113 |
| 69         | NULL      | 10       | 4010          | Account  | Vareforbruk fôr              | 04E63B6D-CA54-423D-8A44-A4ED99861975 |
| 70         | NULL      | 10       | 4901          | Account  | Vareforbruk fôr              | 04E63B6D-CA54-423D-8A44-A4ED99861975 |
| 71         | NULL      | 3        | 4000          | Account  | Andre varekostnader          | DB7FABAB-7ABA-4B9A-9720-1B538D99B3C8 |
| 72         | NULL      | 3        | 4020          | Account  | Andre varekostnader          | DB7FABAB-7ABA-4B9A-9720-1B538D99B3C8 |
| 73         | NULL      | 3        | 4030          | Account  | Andre varekostnader          | DB7FABAB-7ABA-4B9A-9720-1B538D99B3C8 |
| 133        | NULL      | 8        | 4925          | Account  | Beholdningsendring fisk      | A8BA6F19-A792-44A1-AA21-8F79DB24D224 |
| 134        | NULL      | NULL     | NULL          | SubTotal | Sum varekostnader            | NULL                                 |
| 135        | NULL      | 12       | 5000          | Account  | Lønn og sosiale kostnader    | 5C475EDE-3731-4D39-B11A-C8EE72213FF6 |
| 136        | NULL      | 12       | 5001          | Account  | Lønn og sosiale kostnader    | 5C475EDE-3731-4D39-B11A-C8EE72213FF6 |
| 137        | NULL      | 12       | 5005          | Account  | Lønn og sosiale kostnader    | 5C475EDE-3731-4D39-B11A-C8EE72213FF6 |
| 138        | NULL      | 12       | 5009          | Account  | Lønn og sosiale kostnader    | 5C475EDE-3731-4D39-B11A-C8EE72213FF6 |
| 263        | NULL      | NULL     | NULL          | SubTotal | Sum lønnskostnadern          | NULL                                 |
| 462        | NULL      | NULL     | NULL          | SubTotal | RESULTAT ETTER SKATT         | NULL                 

2 个答案:

答案 0 :(得分:2)

如果我理解你的问题,你可以使用:

SELECT  Accountkey, ParentKey,GroupKey,AccountNumber, NEW_PARID
FROM (
             SELECT Accountkey, ParentKey,GroupKey,AccountNumber, AccountKey AS NEW_PARID, LAG(ACCOUNTKEY) OVER (ORDER BY Accountkey) AS PREC
             FROM MYT
             WHERE  GroupKey IS NULL 
             UNION ALL 
             SELECT A.Accountkey, A.ParentKey,A.GroupKey,A.AccountNumber, B.Accountkey AS NEW_PARID, B.PREC
             FROM MYT A 
             INNER JOIN ( SELECT Accountkey, ParentKey,GroupKey,AccountNumber, AccountKey AS NEW_PARID, LAG(ACCOUNTKEY) OVER (ORDER BY Accountkey) AS PREC
             FROM MYT
             WHERE  GroupKey IS NULL) B ON A.Accountkey < B.Accountkey  AND (B.PREC IS NULL OR B.PREC<A.accountKey)
             WHERE A.GroupKey IS NOT NULL 
             AND B.GroupKey IS NULL
) X ORDER BY ACCOUNTKEY

您也可以用这种方式编写它(它是相同的查询):

WITH X AS (SELECT Accountkey, ParentKey,GroupKey,AccountNumber, AccountKey AS NEW_PARID, LAG(ACCOUNTKEY) OVER (ORDER BY Accountkey) AS PREC
             FROM MYT
             WHERE  GroupKey IS NULL)
SELECT X.*
FROM X
UNION ALL 
 SELECT A.Accountkey, A.ParentKey,A.GroupKey,A.AccountNumber, X.Accountkey AS NEW_PARID, X.PREC
 FROM MYT A 
 INNER JOIN X  ON A.Accountkey < X.Accountkey  AND (X.PREC IS NULL OR X.PREC<A.accountKey)
 WHERE A.GroupKey IS NOT NULL

输出(MYT是表的名称,新的parentid列是NEW_PARID):

+------------+-----------+----------+---------------+-----------+
| Accountkey | ParentKey | GroupKey | AccountNumber | NEW_PARID |
+------------+-----------+----------+---------------+-----------+
|          1 | NULL      | 7        | 3040          |        67 |
|          2 | NULL      | 7        | 3041          |        67 |
|          3 | NULL      | 7        | 3081          |        67 |
|          4 | NULL      | 7        | 3082          |        67 |
|          5 | NULL      | 7        | 3083          |        67 |
|          6 | NULL      | 7        | 3085          |        67 |
|          7 | NULL      | 7        | 3086          |        67 |
|          8 | NULL      | 7        | 3087          |        67 |
|          9 | NULL      | 2        | 3000          |        67 |
|         10 | NULL      | 2        | 3010          |        67 |
|         11 | NULL      | 2        | 3020          |        67 |
|         12 | NULL      | 2        | 3030          |        67 |
|         41 | NULL      | 11       | 3050          |        67 |
|         42 | NULL      | 11       | 3600          |        67 |
|         43 | NULL      | 11       | 3601          |        67 |
|         44 | NULL      | 11       | 3610          |        67 |
|         45 | NULL      | 11       | 3615          |        67 |
|         46 | NULL      | 11       | 3690          |        67 |
|         47 | NULL      | 11       | 3691          |        67 |
|         48 | NULL      | 11       | 3701          |        67 |
|         49 | NULL      | 11       | 3705          |        67 |
|         50 | NULL      | 11       | 3720          |        67 |
|         67 | NULL      | NULL     | NULL          |        67 |
|         68 | NULL      | 13       | 4120          |       134 |
|         69 | NULL      | 10       | 4010          |       134 |
|         70 | NULL      | 10       | 4901          |       134 |
|         71 | NULL      | 3        | 4000          |       134 |
|         72 | NULL      | 3        | 4020          |       134 |
|         73 | NULL      | 3        | 4030          |       134 |
|        133 | NULL      | 8        | 4925          |       134 |
|        134 | NULL      | NULL     | NULL          |       134 |
|        135 | NULL      | 12       | 5000          |       263 |
|        136 | NULL      | 12       | 5001          |       263 |
|        137 | NULL      | 12       | 5005          |       263 |
|        138 | NULL      | 12       | 5009          |       263 |
|        263 | NULL      | NULL     | NULL          |       263 |
|        462 | NULL      | NULL     | NULL          |       462 |
+------------+-----------+----------+---------------+-----------+

更新20171221 - 适用于MSSQL 2008 您可以尝试这样做(但如果您有大型数据集,请注意性能):

 SELECT A.ACCOUNTKEY
    , A.PARENTKEY
    , (SELECT MIN(B.ACCOUNTKEY) FROM MYT B WHERE B.GROUPKEY IS NULL AND A.ACCOUNTKEY<=B.ACCOUNTKEY) AS NEW_PARID
FROM MYT A
/* WHERE A.GROUPKEY IS NOT NULL*/

答案 1 :(得分:0)

这是我需要重写以处理SQL Server 2008的代码

$("#load-html").click(function() {
    window.location.href = 'http://yourdomain.com/new-html'
})