SQL Server 2008 R2 running sum - sql-server

I have a table like below.
row_no and product are PK.
+--------+---------+-------+-----+---------------+---------+
| row_no | Product | value | qoh | prev_week_qty | cum_qty |
+--------+---------+-------+-----+---------------+---------+
| 1 | pr:1 | 101 | 101 | NULL | NULL |
| 2 | pr:1 | 201 | 101 | NULL | 100 |
| 3 | pr:1 | 101 | 101 | NULL | NULL |
| 4 | pr:1 | 101 | 101 | NULL | NULL |
| 5 | pr:1 | 183 | 101 | NULL | -18 |
| 6 | pr:1 | 101 | 101 | NULL | NULL |
| 7 | pr:1 | 101 | 101 | NULL | NULL |
| 8 | pr:1 | 149 | 101 | NULL | -34 |
| 9 | pr:1 | 131 | 101 | NULL | -18 |
| 10 | pr:1 | 101 | 101 | NULL | NULL |
| 11 | pr:1 | 113 | 101 | NULL | -18 |
| 12 | pr:1 | 101 | 101 | NULL | NUll |
| 13 | pr:1 | 101 | 101 | NULL | NUll |
| 14 | pr:1 | 101 | 101 | NULL | NUll |
| 17 | pr:1 | 101 | 101 | NULL | NULL |
+--------+---------+-------+-----+---------------+---------+
Is there any way to implement this without usig cusrsor?
Logic: Value = qoh + cum_qty + prev_week_qty
For ex:
For row_no=1, value = qoh+prev_week_qty+cum_qty.
For row_no=2, qoh = (row_no = 1.value), then qoh+ prev_week_qty+cum_qty
For row_no=3, qoh = (row_no = 2.value), then qoh+ prev_week_qty+cum_qty
Expected output:
+--------+---------+-------+-----+---------------+---------+
| row_no | Product | value | qoh | prev_week_qty | cum_qty |
+--------+---------+-------+-----+---------------+---------+
| 1 | pr:1 | 101 | 101 | NULL | NULL |
| 2 | pr:1 | 201 | 101 | NULL | 100 |
| 3 | pr:1 | 201 | 101 | NULL | NULL |
| 4 | pr:1 | 201 | 101 | NULL | NULL |
| 5 | pr:1 | 183 | 101 | NULL | -18 |
| 6 | pr:1 | 183 | 101 | NULL | NULL |
| 7 | pr:1 | 183 | 101 | NULL | NULL |
| 8 | pr:1 | 149 | 101 | NULL | -34 |
| 9 | pr:1 | 131 | 101 | NULL | -18 |
| 10 | pr:1 | 131 | 101 | NULL | NULL |
| 11 | pr:1 | 113 | 101 | NULL | -18 |
| 12 | pr:1 | 113 | 101 | NULL | NUll |
| 13 | pr:1 | 113 | 101 | NULL | NUll |
| 14 | pr:1 | 113 | 101 | NULL | NUll |
| 17 | pr:1 | 101 | 101 | NULL | NULL |
+--------+---------+-------+-----+---------------+---------+
I am using SQL Server 2008 R2.

In SQL SERVER 2012+ you can use SUM()OVER(ORDER BY) trick unfortunately you are using older version. Try something like this
SELECT *
FROM Yourtable A
CROSS apply (SELECT Sum(Isnull([cum_qty], 0)
+ Isnull(prev_week_qty, 0) + CASE WHEN row_no = 1 THEN qoh ELSE 0 END) su
FROM Yourtable B
WHERE a.[row_no] >= b.[row_no]) cs

Related

Sum, Group by and Null

I'm dipping my toes into SQL. I have the following table
+------+----+------+------+-------+
| Type | ID | QTY | Rate | Name |
+------+----+------+------+-------+
| B | 1 | 1000 | 21 | Jack |
| B | 2 | 2000 | 12 | Kevin |
| B | 1 | 3000 | 24 | Jack |
| B | 1 | 1000 | 23 | Jack |
| B | 3 | 200 | 13 | Mary |
| B | 2 | 3000 | 12 | Kevin |
| B | 4 | 4000 | 44 | Chris |
| B | 4 | 5000 | 43 | Chris |
| B | 3 | 1000 | 26 | Mary |
+------+----+------+------+-------+
I don't know how I would leverage Sum and Group by to achieve the following result.
+------+----+------+------+-------+------------+
| Type | ID | QTY | Rate | Name | Sum of QTY |
+------+----+------+------+-------+------------+
| B | 1 | 1000 | 21 | Jack | 5000 |
| B | 1 | 3000 | 24 | Jack | Null |
| B | 1 | 1000 | 23 | Jack | Null |
| B | 2 | 3000 | 12 | Kevin | 5000 |
| B | 2 | 3000 | 12 | Kevin | Null |
| B | 3 | 200 | 13 | Mary | 1200 |
| B | 3 | 1000 | 26 | Mary | Null |
| B | 4 | 4000 | 44 | Chris | 9000 |
| B | 4 | 5000 | 43 | Chris | Null |
+------+----+------+------+-------+------------+
Any help is appreciated!
You can use window function :
select t.*,
(case when row_number() over (partition by type, id order by name) = 1
then sum(qty) over (partition by type, id order by name)
end) as Sum_of_QTY
from table t;

SQL Server Merge rows using lag?

i have a table that , have Intime, OutTime, zonechk flag
if 1 mean inside , null mean outside , i need to merge them for reporting Propose for example
inside 10:10 to 10:40
inside 11:10 to 12:30
outside 12:31 to 14:00
inside 14:10 to 14:40
inside 15:10 to 15:30
to be
inside 10:10 to 12:30
outside 12:31 to 14:00
inside 14:10 to 15:40
+--------+--------------+----------------+--------------+----------+-------------------------+--------+---------+
| Number | plate_number | move_from_date | move_to_date | Duration | inTime | zoneid | zonechk |
+--------+--------------+----------------+--------------+----------+-------------------------+--------+---------+
| 5934 | NULL | 1507713204 | 1508147403 | 434199 | 2017-10-11 09:13:24.100 | 54 | 1 |
| 5934 | NULL | 1507793515 | 1507793924 | 409 | 2017-10-12 07:31:55.310 | 709 | NULL |
| 5934 | NULL | 1508051465 | 1508051861 | 396 | 2017-10-15 07:11:05.010 | 709 | 1 |
| 5934 | NULL | 1508139025 | 1508139551 | 526 | 2017-10-16 07:30:25.570 | 709 | 1 |
| 5934 | NULL | 1508147732 | 1508148337 | 605 | 2017-10-16 09:55:32.650 | 698 | NULL |
| 5934 | NULL | 1508148802 | 1508235374 | 86572 | 2017-10-16 10:13:22.060 | 54 | 1 |
| 5934 | NULL | 1508227127 | 1508227707 | 580 | 2017-10-17 07:58:47.040 | 709 | NULL |
| 5934 | NULL | 1508235727 | 1508236062 | 335 | 2017-10-17 10:22:07.150 | 698 | 1 |
| 5934 | NULL | 1508236426 | 1508320755 | 84329 | 2017-10-17 10:33:46.040 | 54 | 1 |
| 5934 | NULL | 1508312035 | 1508312473 | 438 | 2017-10-18 07:33:55.780 | 709 | 1 |
| 5934 | NULL | 1508321089 | 1508321767 | 678 | 2017-10-18 10:04:49.110 | 698 | 1 |
| 5934 | NULL | 1508322313 | 1508405959 | 83646 | 2017-10-18 10:25:13.990 | 54 | 1 |
| 5934 | NULL | 1508398316 | 1508398778 | 462 | 2017-10-19 07:31:56.680 | 709 | 1 |
| 5934 | NULL | 1508406309 | 1508406811 | 502 | 2017-10-19 09:45:09.260 | 698 | NULL |
| 5934 | NULL | 1508407153 | 1508575805 | 168652 | 2017-10-19 09:59:13.857 | 54 | 1 |
| 5934 | NULL | 1508565909 | 1508566376 | 467 | 2017-10-21 06:05:09.240 | 709 | NULL |
| 5934 | NULL | 1508576176 | 1508576601 | 425 | 2017-10-21 08:56:16.473 | 698 | 1 |
| 5934 | NULL | 1508577010 | 1508834353 | 257343 | 2017-10-21 09:10:10.710 | 54 | 1 |
| 5934 | NULL | 1508584759 | 1508585455 | 696 | 2017-10-21 11:19:19.930 | 709 | NULL |
| 5934 | NULL | 1508659492 | 1508660021 | 529 | 2017-10-22 08:04:52.490 | 709 | 1 |
| 5934 | NULL | 1508741980 | 1508742462 | 482 | 2017-10-23 06:59:40.960 | 709 | 1 |
| 5934 | NULL | 1508749508 | 1508750050 | 542 | 2017-10-23 09:05:08.893 | 709 | NULL |
| 5934 | NULL | 1508834742 | 1508835409 | 667 | 2017-10-24 08:45:42.960 | 698 | 1 |
| 5934 | NULL | 1508917280 | 1508917694 | 414 | 2017-10-25 07:41:20.940 | 709 | 1 |
| 5934 | NULL | 1508966861 | 1509000828 | 33967 | 2017-10-25 21:27:41.490 | 54 | 1 |
| 5934 | NULL | 1509000911 | 1509002958 | 2047 | 2017-10-26 06:55:11.330 | 54 | 1 |
| 5934 | NULL | 1509001844 | 1509002376 | 532 | 2017-10-26 07:10:44.090 | 709 | NULL |
| 5934 | NULL | 1509003211 | 1509007113 | 3902 | 2017-10-26 07:33:31.023 | 54 | 1 |
| 5934 | NULL | 1509006789 | 1509006863 | 74 | 2017-10-26 08:33:09.350 | 54 | 1 |
| 5934 | NULL | 1509006866 | 1509007049 | 183 | 2017-10-26 08:34:26.130 | 54 | 1 |
| 5934 | NULL | 1509007257 | 1509009354 | 2097 | 2017-10-26 08:40:57.170 | 54 | 1 |
| 5934 | NULL | 1509008978 | 1509009089 | 111 | 2017-10-26 09:09:38.660 | 54 | 1 |
| 5934 | NULL | 1509009092 | 1509009231 | 139 | 2017-10-26 09:11:32.420 | 54 | 1 |
| 5934 | NULL | 1509009458 | 1509009946 | 488 | 2017-10-26 09:17:38.590 | 54 | 1 |
| 5934 | NULL | 1509009529 | 1509009608 | 79 | 2017-10-26 09:18:49.600 | 54 | 1 |
| 5934 | NULL | 1509009610 | 1509009757 | 147 | 2017-10-26 09:20:10.990 | 54 | 1 |
| 5934 | NULL | 1509009759 | 1509009909 | 150 | 2017-10-26 09:22:39.610 | 54 | 1 |
| 5934 | NULL | 1509010472 | 1509010787 | 315 | 2017-10-26 09:34:32.270 | 698 | 1 |
| 5934 | NULL | 1509011192 | 1509011367 | 175 | 2017-10-26 09:46:32.530 | 54 | 1 |
| 5934 | NULL | 1509011370 | 1509011424 | 54 | 2017-10-26 09:49:30.100 | 54 | 1 |
| 5934 | NULL | 1509011644 | 1509016547 | 4903 | 2017-10-26 09:54:04.390 | 54 | 1 |
| 5934 | NULL | 1509016793 | 1509018783 | 1990 | 2017-10-26 11:19:53.370 | 54 | 1 |
| 5934 | NULL | 1509018880 | 1509021232 | 2352 | 2017-10-26 11:54:40.680 | 54 | 1 |
| 5934 | NULL | 1509021327 | 1509041423 | 20096 | 2017-10-26 12:35:27.760 | 54 | 1 |
| 5934 | NULL | 1509042027 | 1509179109 | 137082 | 2017-10-26 18:20:27.460 | 54 | 1 |
| 5934 | NULL | 1509174809 | 1509175309 | 500 | 2017-10-28 07:13:29.010 | 709 | NULL |
| 5934 | NULL | 1509179335 | 1509179907 | 572 | 2017-10-28 08:28:55.660 | 54 | 1 |
| 5934 | NULL | 1509180005 | 1509180828 | 823 | 2017-10-28 08:40:05.890 | 54 | 1 |
| 5934 | NULL | 1509180925 | 1509187555 | 6630 | 2017-10-28 08:55:25.270 | 54 | 1 |
| 5934 | NULL | 1509187624 | 1509189851 | 2227 | 2017-10-28 10:47:04.630 | 54 | 1 |
| 5934 | NULL | 1509190143 | 1509190301 | 158 | 2017-10-28 11:29:03.580 | 54 | 1 |
| 5934 | NULL | 1509190387 | 1509191479 | 1092 | 2017-10-28 11:33:07.230 | 54 | 1 |
| 5934 | NULL | 1509191575 | 1509192224 | 649 | 2017-10-28 11:52:55.150 | 54 | 1 |
| 5934 | NULL | 1509192314 | 1509192479 | 165 | 2017-10-28 12:05:14.800 | 54 | 1 |
| 5934 | NULL | 1509192588 | 1509218423 | 25835 | 2017-10-28 12:09:48.670 | 54 | 1 |
| 5934 | NULL | 1509219048 | 1509224551 | 5503 | 2017-10-28 19:30:48.440 | 54 | 1 |
| 5934 | NULL | 1509225176 | 1509260681 | 35505 | 2017-10-28 21:12:56.600 | 54 | 1 |
| 5934 | NULL | 1509260770 | 1509269210 | 8440 | 2017-10-29 07:06:10.840 | 54 | 1 |
| 5934 | NULL | 1509261874 | 1509262382 | 508 | 2017-10-29 07:24:34.730 | 709 | NULL |
| 5934 | NULL | 1509269612 | 1509270116 | 504 | 2017-10-29 09:33:32.580 | 698 | 1 |
| 5934 | NULL | 1509270123 | 1509270136 | 13 | 2017-10-29 09:42:03.510 | 698 | 1 |
| 5934 | NULL | 1509270499 | 1509271818 | 1319 | 2017-10-29 09:48:19.940 | 54 | 1 |
| 5934 | NULL | 1509271880 | 1509272029 | 149 | 2017-10-29 10:11:20.030 | 54 | 1 |
| 5934 | NULL | 1509339400 | 1509348800 | 9400 | 2017-10-30 04:56:40.890 | 54 | 1 |
| 5934 | NULL | 1509348868 | 1509350133 | 1265 | 2017-10-30 07:34:28.720 | 54 | 1 |
| 5934 | NULL | 1509349430 | 1509349892 | 462 | 2017-10-30 07:43:50.690 | 709 | 1 |
| 5934 | NULL | 1509350202 | 1509352410 | 2208 | 2017-10-30 07:56:42.050 | 54 | 1 |
| 5934 | NULL | 1509352779 | 1509353737 | 958 | 2017-10-30 08:39:39.040 | 54 | 1 |
| 5934 | NULL | 1509353800 | 1509354320 | 520 | 2017-10-30 08:56:40.150 | 54 | 1 |
| 5934 | NULL | 1509354782 | 1509358601 | 3819 | 2017-10-30 09:13:02.250 | 54 | 1 |
| 5934 | NULL | 1509359418 | 1509432505 | 73087 | 2017-10-30 10:30:18.960 | 54 | 1 |
| 5934 | NULL | 1509432786 | 1509432917 | 131 | 2017-10-31 06:53:06.880 | 54 | 1 |
| 5934 | NULL | 1509432999 | 1509433705 | 706 | 2017-10-31 06:56:39.133 | 54 | 1 |
| 5934 | NULL | 1509433790 | 1509438679 | 4889 | 2017-10-31 07:09:50.570 | 54 | 1 |
| 5934 | NULL | 1509438792 | 1509438859 | 67 | 2017-10-31 08:33:12.063 | 54 | 1 |
| 5934 | NULL | 1509438962 | 1509441624 | 2662 | 2017-10-31 08:36:02.810 | 54 | 1 |
| 5934 | NULL | 1509443082 | 1509443985 | 903 | 2017-10-31 09:44:42.670 | 54 | 1 |
| 5934 | NULL | 1509443897 | 1509443930 | 33 | 2017-10-31 09:58:17.230 | 54 | 1 |
| 5934 | NULL | 1509444103 | 1509447041 | 2938 | 2017-10-31 10:01:43.537 | 54 | 1 |
| 5934 | NULL | 1509447618 | 1509450979 | 3361 | 2017-10-31 11:00:18.440 | 54 | 1 |
| 5934 | NULL | 1509451066 | 1509451371 | 305 | 2017-10-31 11:57:46.560 | 54 | 1 |
+--------+--------------+----------------+--------------+----------+-------------------------+--------+---------+
how to achieve that using lag with delete in TSQL ? lag must be by number and zoneId with inTime ASC
Using cross apply can be helpful here, e.g.
available as a demo at SQL Fiddle
CREATE TABLE Table1
([Number] int, [plate_number] varchar(4), [move_from_date] int, [move_to_date] int, [Duration] int, [inTime] datetime, [zoneid] int, [zonechk] varchar(4))
;
INSERT INTO Table1
([Number], [plate_number], [move_from_date], [move_to_date], [Duration], [inTime], [zoneid], [zonechk])
VALUES
(5934, NULL, 1507713204, 1508147403, 434199, '2017-10-11 09:13:24', 54, '1'),
(5934, NULL, 1507793515, 1507793924, 409, '2017-10-12 07:31:55', 709, NULL),
(5934, NULL, 1508051465, 1508051861, 396, '2017-10-15 07:11:05', 709, '1'),
(5934, NULL, 1508139025, 1508139551, 526, '2017-10-16 07:30:25', 709, '1'),
(5934, NULL, 1508147732, 1508148337, 605, '2017-10-16 09:55:32', 698, NULL),
(5934, NULL, 1508148802, 1508235374, 86572, '2017-10-16 10:13:22', 54, '1'),
(5934, NULL, 1508227127, 1508227707, 580, '2017-10-17 07:58:47', 709, NULL),
(5934, NULL, 1508235727, 1508236062, 335, '2017-10-17 10:22:07', 698, '1')
;
Query 1:
select
*
from table1 t
cross apply (
select top(1) move_to_date as next_move_to
from table1 nxt
where nxt.zonechk IS NULL
and nxt.move_to_date > t.move_from_date
order by nxt.move_from_date, nxt.move_to_date
) ca
where zonechk = 1
Results:
| Number | plate_number | move_from_date | move_to_date | Duration | inTime | zoneid | zonechk | next_move_to |
|--------|--------------|----------------|--------------|----------|----------------------|--------|---------|--------------|
| 5934 | (null) | 1507713204 | 1508147403 | 434199 | 2017-10-11T09:13:24Z | 54 | 1 | 1507793924 |
| 5934 | (null) | 1508051465 | 1508051861 | 396 | 2017-10-15T07:11:05Z | 709 | 1 | 1508148337 |
| 5934 | (null) | 1508139025 | 1508139551 | 526 | 2017-10-16T07:30:25Z | 709 | 1 | 1508148337 |
| 5934 | (null) | 1508148802 | 1508235374 | 86572 | 2017-10-16T10:13:22Z | 54 | 1 | 1508227707 |

Trying to create a parent-child hierarchy in sql server

I have a data set that is sorted by account key. when coming to certain rows which have NULL as group key, it should add current account key as a parent key for all above rows which have NULL as parentkey. So when coming to the next row with null as group key, you would set the current account key as parent key for all rows above that have parent key like null.
I have tried to copy a dataset below as mark down table but as you see I can't say I succeeded very well, but I hope some of you can help with the t-sql syntax to create a parent-child hierarchy of this
| 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
If I understood your question you could use:
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
You can write it in this way too (it's the same query):
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
Output (MYT is the name of the table, the new parentid column is 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 |
+------------+-----------+----------+---------------+-----------+
Updated 20171221 - for MSSQL 2008
You can try this (but pay attention for performance if you have a large dataset):
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*/
This is the code I need to rewrite to work on SQL Server 2008
SELECT AccountKey,
LineName,
AccountName,
GroupKey,
AccountNumber,
ParentAccountKey
INTO tempAccount
FROM
(
SELECT AccountKey,
LineName,
AccountName,
GroupKey,
AccountNumber,
AccountKey AS ParentAccountKey,
LAG(AccountKey) OVER(ORDER BY AccountKey) AS PREC
FROM tempTable2
WHERE GroupKey IS NULL
UNION ALL
SELECT A.AccountKey,
A.LineName,
A.AccountName,
A.GroupKey,
A.AccountNumber,
B.AccountKey AS ParentAccountKey,
B.PREC
FROM tempTable2 A
INNER JOIN
(
SELECT AccountKey,
LineName,
AccountName,
GroupKey,
AccountNumber,
AccountKey AS ParentAccountKey,
LAG(AccountKey) OVER(ORDER BY AccountKey) AS PREC
FROM tempTable2
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;

Reformat existing table from paired columns into rows

For example I have a table with 5 rows and 7 columns, I wish to move the last two columns into the previous two columns. New format of table would now be 10 rows and 5 columns
Present Table format
+-----+------------+----------+------------+---------------+------------+---------------+
| id | VisitDate | fkFamily | child1.DOB | child1.Gender | child2.DOB | child2.Gender |
+-----+------------+----------+------------+---------------+------------+---------------+
| 78 | 19/04/2010 | 277 | 14/03/2009 | 0 | NULL | NULL |
| 79 | 20/04/2010 | 289 | 12/08/2007 | 0 | NULL | NULL |
| 107 | 20/04/2010 | 191 | NULL | NULL | NULL | NULL |
| 108 | 20/04/2010 | 259 | NULL | NULL | 31/03/2010 | 1 |
| 109 | 20/04/2010 | 126 | NULL | NULL | NULL | NULL |
+-----+------------+----------+------------+---------------+------------+---------------+
New table format
+-----+------------+----------+------------+----------------------+
| id | VisitDate | fkFamily | child.DOB | child.Gender |
+-----+------------+----------+------------+----------------------+
| 78 | 19/04/2010 | 277 | 14/03/2009 | 0 |
| 79 | 20/04/2010 | 289 | 12/08/2007 | 0 |
| 107 | 20/04/2010 | 191 | NULL | NULL |
| 108 | 20/04/2010 | 259 | NULL | NULL |
| 109 | 20/04/2010 | 126 | NULL | NULL |
| 78 | 19/04/2010 | 277 | NULL | NULL |
| 79 | 20/04/2010 | 289 | NULL | NULL |
| 107 | 20/04/2010 | 191 | NULL | NULL |
| 108 | 20/04/2010 | 259 | 31/03/2010 | 1 |
| 109 | 20/04/2010 | 126 | NULL | NULL |
+-----+------------+----------+------------+----------------------+
You can get the final result by unpivoting the columns Child1_DOB, Child1_Gender, etc. Starting in SQL Server 2005, the unpivot function was made available but for your case I'd actually use CROSS APPLY so you can unpivot the Child1, and Child2 values in pairs.
The syntax would be:
select
t.id,
t.visitdate,
t.fkFamily,
c.child_DOB,
c.child_Gender
from yourtable t
cross apply
(
select child1_DOB, child1_Gender union all
select child2_DOB, child2_Gender
) c (child_DOB, child_Gender);
See SQL Fiddle with Demo
Then you could also include an identifier for each of the values so you know if it belonged to child one or two:
select
t.id,
t.visitdate,
t.fkFamily,
c.child,
c.child_DOB,
c.child_Gender
from yourtable t
cross apply
(
select 'Child1', child1_DOB, child1_Gender union all
select 'Child2', child2_DOB, child2_Gender
) c (child, child_DOB, child_Gender)
See SQL Fiddle with Demo. These give a result similar to:
| ID | VISITDATE | FKFAMILY | CHILD_DOB | CHILD_GENDER |
|-----|------------|----------|------------|--------------|
| 78 | 19/04/2010 | 277 | 14/03/2009 | 0 |
| 78 | 19/04/2010 | 277 | (null) | (null) |
| 79 | 20/04/2010 | 289 | 12/08/2007 | 0 |
| 79 | 20/04/2010 | 289 | (null) | (null) |
| 107 | 20/04/2010 | 191 | (null) | (null) |
| 107 | 20/04/2010 | 191 | (null) | (null) |
| 108 | 20/04/2010 | 259 | (null) | (null) |
| 108 | 20/04/2010 | 259 | 31/03/2010 | 1 |
| 109 | 20/04/2010 | 126 | (null) | (null) |
| 109 | 20/04/2010 | 126 | (null) | (null) |
You could reformat the table into something like this by using UNION:-
SELECT * FROM (
SELECT id, VisitDate, fkFamily, child1_DOB as child_DOB, child1_Gender as child_Gender
FROM yourtable
UNION
SELECT id, VisitDate, fkFamily, child2_DOB, child2_Gender
FROM yourtable) as temp
FIDDLE
You could use SELECT INTO if you wanted to create a new table from the results, for example:-
SELECT * INTO yournewtable FROM (
SELECT id, VisitDate, fkFamily, child1_DOB as child_DOB, child1_Gender as child_Gender
FROM yourtable
UNION
SELECT id, VisitDate, fkFamily, child2_DOB, child2_Gender
FROM yourtable) as temp

How do I generate lft and rght values for a cakephp 2.0 tree?

I've read that if you have a model that $actsAs = array('Tree'), that you can simply set the parent_id for your seed data, and a call to $this->Model->recover() should generate the proper lft and rght values for you, but when I do this, Cake seems to generate random values every time. The values vary from very large (in the thousands) to negative values. I've checked for circular references and found none as well. What could be wrong here?
SQL:
create table menus (
id int auto_increment not null,
parent_id int null ,
lft int null ,
rght int null ,
title varchar(1024) not null,
path varchar(1024) not null,
constraint pk_menus primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This is the seeded data: After one Model->recover()
+----+-----------+------+------+ +----+-----------+------+------+
| id | parent_id | lft | rght | | id | parent_id | lft | rght |
+----+-----------+------+------+ +----+-----------+------+------+
| 1 | NULL | NULL | NULL | | 1 | NULL | 595 | 619 |
| 7 | 1 | NULL | NULL | | 7 | 1 | 619 | 567 |
| 6 | 1 | NULL | NULL | | 6 | 1 | 627 | 595 |
| 5 | 1 | NULL | NULL | | 5 | 1 | 600 | 621 |
| 4 | 1 | NULL | NULL | | 4 | 1 | 603 | 621 |
| 3 | 1 | NULL | NULL | | 3 | 1 | 619 | 529 |
| 2 | 1 | NULL | NULL | | 2 | 1 | 595 | 529 |
| 8 | 2 | NULL | NULL | | 8 | 2 | 627 | 628 |
| 13 | 3 | NULL | NULL | | 13 | 3 | 595 | 567 |
| 12 | 3 | NULL | NULL | | 12 | 3 | 627 | 621 |
| 11 | 3 | NULL | NULL | | 11 | 3 | 595 | 631 |
| 10 | 3 | NULL | NULL | | 10 | 3 | 604 | 529 |
| 9 | 3 | NULL | NULL | | 9 | 3 | 595 | 567 |
| 14 | 5 | NULL | NULL | | 14 | 5 | 628 | 629 |
| 15 | 5 | NULL | NULL | | 15 | 5 | 567 | 529 |
| 16 | 5 | NULL | NULL | | 16 | 5 | 619 | 600 |
| 17 | 5 | NULL | NULL | | 17 | 5 | 627 | 605 |
| 21 | 6 | NULL | NULL | | 21 | 6 | 567 | 619 |
| 20 | 6 | NULL | NULL | | 20 | 6 | 595 | 567 |
| 19 | 6 | NULL | NULL | | 19 | 6 | 619 | 600 |
| 18 | 6 | NULL | NULL | | 18 | 6 | 567 | 529 |
| 22 | 10 | NULL | NULL | | 22 | 10 | 567 | 619 |
| 23 | 11 | NULL | NULL | | 23 | 11 | 64 | 621 |
| 24 | 12 | NULL | NULL | | 24 | 12 | 627 | 621 |
| 25 | 13 | NULL | NULL | | 25 | 13 | 605 | 595 |
| 32 | 16 | NULL | NULL | | 32 | 16 | 628 | 627 |
| 31 | 16 | NULL | NULL | | 31 | 16 | 567 | 619 |
| 30 | 16 | NULL | NULL | | 30 | 16 | 64 | 621 |
| 29 | 16 | NULL | NULL | | 29 | 16 | 567 | 619 |
| 28 | 16 | NULL | NULL | | 28 | 16 | 595 | 567 |
| 27 | 16 | NULL | NULL | | 27 | 16 | 627 | 621 |
| 26 | 16 | NULL | NULL | | 26 | 16 | 605 | 595 |
| 33 | 17 | NULL | NULL | | 33 | 17 | 567 | 619 |
| 37 | 19 | NULL | NULL | | 37 | 19 | 52 | 619 |
| 36 | 19 | NULL | NULL | | 36 | 19 | 52 | 619 |
| 35 | 19 | NULL | NULL | | 35 | 19 | 595 | 619 |
| 34 | 19 | NULL | NULL | | 34 | 19 | 63 | 621 |
| 38 | 20 | NULL | NULL | | 38 | 20 | 63 | 621 |
| 39 | 20 | NULL | NULL | | 39 | 20 | 63 | 621 |
| 40 | 21 | NULL | NULL | | 40 | 21 | 605 | 595 |
+----+-----------+------+------+ +----+-----------+------+------+
I found that if I set the lft and rght values of the top level item to 1 and 2 respectively, recover() now generates the rest of the values properly. I find this to be a bug, but not a terrible one.

Resources