Combine fields with overlapping dates into one field (qlik sense) - overlapping

Hello to the whole community!
There is a code that combine many field with overlapping dates into one field.
The code is below
Table_one:
load *
INLINE [
id_client | id_question| date_open | date_close
YZIYR00R | 14534534 | 05.10.2022 | 30.10.2022
YZIYR00R | 14786543 | 26.10.2022 | 27.10.2022
YZIYR00R | 87634957 | 27.10.2022 | 28.10.2022
YZIYR00R | 12398750 | 27.10.2022 | 28.10.2022
YZIYR00R | 57548555 | 27.10.2022 | 28.10.2022
YZIYR00R | 36485023 | 29.10.2022 | 30.10.2022
] (delimiter is '|');
Tmp:
LOAD *, if(previous(date_close) >= date_open and previous(id_client) = id_client,
peek(question_group), id_question) as question_group
Resident Table_one
ORDER BY id_client, date_open, date_close;
drop table Table_one;
SampleData:
LOAD id_client, question_group as id_question,
FirstSortedValue(date_open, recno()) as date_open,
FirstSortedValue(date_close, -recno()) as date_close
Resident Tmp
GROUP BY id_client, question_group;
drop table Tmp;
So the last line doesn’t fall in the interval. The problem is that the code only checks the previous and next lines, if you add the filed (my last line in code), it will not fall into the interval because is compared to the previous one.
And I would like the intersecting intervals to join one, where the start date would be the minimum number of the intersecting group and the end date would be the maximum.
Than I wrote the next following code:
Table_one:
load *
INLINE [
id_client | id_question| date_open | date_close
YZIYR00R | 14534534 | 11.01.2022 | 11.01.2022
YZIYR00R | 14786543 | 11.01.2022 | 11.01.2022
YZIYR00R | 87634957 | 11.01.2022 | 11.01.2022
YZIYR00R | 12398750 | 11.01.2022 | 12.01.2022
YZIYR00R | 57548555 | 13.01.2022 | 13.01.2022
YZIYR00R | 36485023 | 13.01.2022 | 14.01.2022
YZIYR00R | 09748361 | 13.01.2022 | 13.01.2022
YZIYR00R | 56419453 | 13.01.2022 | 15.01.2022
] (delimiter is '|');
Tmp:
LOAD *, if(previous(date_close) >= date_open and previous(id_client) = id_client,
peek(question_group), id_question) as question_group
Resident Table_one
ORDER BY id_client,date_close,date_open;
drop table Table_one;
next:
load id_client, question_group as id_question, min(date_open) as date_open, max(date_close) as date_close
Resident Tmp
Group by id_client, question_group;
drop table Tmp;
but with the data below it will no longer work correctly:
Table_one:
load *
INLINE [
id_client | id_question| date_open | date_close
YZIYR00R | 14534534 | 03.10.2022 | 03.10.2022
YZIYR00R | 14786543 | 04.10.2022 | 04.10.2022
YZIYR00R | 87634957 | 05.10.2022 | 02.12.2022
YZIYR00R | 12398750 | 06.10.2022 | 05.10.2022
YZIYR00R | 57548555 | 08.10.2022 | 06.10.2022
YZIYR00R | 36485023 | 17.10.2022 | 11.10.2022
YZIYR00R | 09748361 | 19.10.2022 | 18.10.2022
YZIYR00R | 56419453 | 20.10.2022 | 19.10.2022
YZIYR00R | 64324123 | 31.10.2022 | 26.10.2022
YZIYR00R | 53634322 | 01.11.2022 | 31.10.2022
YZIYR00R | 56787656 | 03.11.2022 | 03.11.2022
YZIYR00R | 78946487 | 09.11.2022 | 03.11.2022
YZIYR00R | 11111111 | 09.11.2022 | 09.11.2022
YZIYR00R | 98541484 | 10.11.2022 | 11.11.2022
YZIYR00R | 45487874 | 29.11.2022 | 23.11.2022
YZIYR00R | 26548459 | 02.12.2022 | 29.11.2022
] (delimiter is '|');

Related

How can I improve the response time of this query in Oracle

this query takes 24 seconds and returns 1891 results:
SELECT p.STATE, p.REFNUM, p.CODE, p.TYPE, i.STATE, pj.NAME, pj.DOCUMENT
TABLE p
inner join TABLE2 i on i.REFNUM = p.REFNUM
inner join TABLE3 pj on pj.NUMBER = i.NUMBER and p.OFIC_ID = pj.OFIC_ID and p.PUB_ID = pj.PUB_ID
inner join OFICE o on t.OFIC_ID = p.OFIC_ID and o.PUB_ID = p.PUB_ID
inner join GROUP glad on glad.GROUP_CODE=p.GROUP_CODE
WHERE glad.GROUP_TYPE ='3' AND i.STATE = '1'
AND p.PUB_ID IN ('05','11','12','09','08','13','04','02','01','06','10','03','07','14')
AND pj.NAME LIKE 'BANK%'
ORDER BY o.NAME,p.ID;
I have these indexes:
CREATE INDEX IND_TABLE1_REFNUM_ZONE ON TABLE1 (PUB_ID, OFIC_ID, REFNUM, ZONE_ID)
CREATE INDEX IND_TABLE1_REFNUMPUB ON TABLE1 (REFNUM, PUB_ID, OFIC_ID, GROUP_CODE );
CREATE INDEX IND_TABLE1_GROUP ON TABLE1 (PUB_ID, GROUP_CODE, REFNUM, OFIC_ID)
CREATE INDEX IND_TABLE2_REF ON TABLE2 (REFNUM, NUMBER, STATE);
CREATE INDEX IND_TABLE2_QUERY ON TABLE2 (NUMBER, TYPE, STATE, REFNUM, NUM, CODE);
CREATE INDEX IND_TABLE2_REFNUM ON TABLE2 (REFNUM)
CREATE INDEX IND_TABLE2_NUMBER ON TABLE2 (NUMBER)
CREATE INDEX IND_TABLE3_NUM ON TABLE3 (NUMBER, PUB_ID, OFIC_ID, NAME );
CREATE INDEX IND_TABLE3_NAME ON TABLE3 ( NAME );
CREATE INDEX IND_GROUP_COD ON GROUP (GROUP_CODE, GROUP_TYPE)
I made the following queries to see how many records are in each table:
SELECT count(*) FROM TABLE1 --> 18298458 results
SELECT count(*) FROM TABLE2 --> 60627924 results
SELECT count(*) FROM TABLE3 --> 18425913 results
SELECT count(*) FROM OFICE --> 65 results
SELECT count(*) FROM TABLE1 p INNER JOIN GROUP glad on glad.GROUP_CODE=p.GROUP_CODE where glad.GROUP_TYPE ='3' AND p.PUB_ID IN ('05','11','12','09','08','13','04','02','01','06','10','03','07','14') --> 1314077 results
SELECT count(*) FROM TABLE1 p INNER JOIN GROUP glad on glad.GROUP_CODE=p.GROUP_CODE where glad.GROUP_TYPE ='3' AND p.PUB_ID IN ('05') --> 53754 results
SELECT count(*) FROM TABLE3 WHERE NAME LIKE 'BANK%' --> 1922081 results
this is the plan generated by oracle:
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 291K| 38M| 384K| | |
| 1 | SORT ORDER BY | | 291K| 38M| 384K| | |
| 2 | HASH JOIN | | 291K| 38M| 375K| | |
| 3 | TABLE ACCESS FULL | OFICE | 64 | 960 | 3 | | |
| 4 | HASH JOIN | | 291K| 34M| 375K| | |
| 5 | INDEX SKIP SCAN | IND_GROUP_COD | 47 | 329 | 1 | | |
| 6 | HASH JOIN | | 452K| 50M| 375K| | |
| 7 | PART JOIN FILTER CREATE | :BF0000 | 452K| 50M| 375K| | |
| 8 | NESTED LOOPS | | 452K| 50M| 375K| | |
| 9 | NESTED LOOPS | | | | | | |
| 10 | STATISTICS COLLECTOR | | | | | | |
| 11 | HASH JOIN | | 2100K| 166M| 252K| | |
| 12 | NESTED LOOPS | | 2100K| 166M| 252K| | |
| 13 | STATISTICS COLLECTOR | | | | | | |
| 14 | PARTITION RANGE ALL | | 1681K| 89M| 82582 | 1 | 19 |
| 15 | PARTITION HASH ALL | | 1681K| 89M| 82582 | 1 | 32 |
| 16 | TABLE ACCESS FULL | TABLE3 | 1681K| 89M| 82582 | 1 | 608 |
| 17 | INDEX RANGE SCAN | IND_TABLE2_QUERY | 1 | 27 | 103K| | |
| 18 | INDEX FAST FULL SCAN | IND_TABLE2_QUERY | 32M| 845M| 103K| | |
| 19 | INDEX RANGE SCAN | IND_TABLE1_REFNUM_ZONE| | | | | |
| 20 | TABLE ACCESS BY GLOBAL INDEX ROWID| TABLE1 | 1 | 35 | 70380 | ROWID | ROWID |
| 21 | PARTITION RANGE ALL | | 19M| 650M| 70380 | 1 | 19 |
| 22 | PARTITION HASH JOIN-FILTER | | 19M| 650M| 70380 |:BF0000|:BF0000|
| 23 | TABLE ACCESS FULL | TABLE1 | 19M| 650M| 70380 | 1 | 608 |
-----------------------------------------------------------------------------------------------------------------
I think it takes time because this one is using TABLE ACCESS FULL for TABLE1 and TABLE3
if I perform the query filtering only PUB_ID='05' instead of all the numbers in the above query, the query returns 181 results and takes 8 seconds and in that case oracle generates this plan:
--------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 797 | 108K| 312K| | |
| 1 | SORT ORDER BY | | 797 | 108K| 312K| | |
| 2 | NESTED LOOPS | | 797 | 108K| 312K| | |
| 3 | HASH JOIN | | 1238 | 160K| 312K| | |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| OFICE | 3 | 45 | 2 | | |
| 5 | INDEX RANGE SCAN | SYS_C0034405 | 3 | | 1 | | |
| 6 | HASH JOIN | | 2091 | 240K| 312K| | |
| 7 | PART JOIN FILTER CREATE | :BF0000 | 66316 | 5375K| 241K| | |
| 8 | NESTED LOOPS | | 66316 | 5375K| 241K| | |
| 9 | PARTITION RANGE ALL | | 53085 | 2903K| 82490 | 1 | 19 |
| 10 | PARTITION HASH ALL | | 53085 | 2903K| 82490 | 1 | 32 |
| 11 | TABLE ACCESS FULL | TABLE3 | 53085 | 2903K| 82490 | 1 | 608 |
| 12 | INDEX RANGE SCAN | IND_TABLE2_QUERY | 1 | 27 | 3 | | |
| 13 | PARTITION RANGE ALL | | 762K| 25M| 68657 | 1 | 19 |
| 14 | PARTITION HASH JOIN-FILTER | | 762K| 25M| 68657 |:BF0000|:BF0000|
| 15 | TABLE ACCESS FULL | TABLE1 | 762K| 25M| 68657 | 1 | 608 |
| 16 | INDEX RANGE SCAN | IND_GROUP_COD | 1 | 7 | 0 | | |
--------------------------------------------------------------------------------------------------------------
SYS_C0034405 is the primary key of OFFICE which contains these fields: (PUB_ID, REG_ID)
if in addition to filtering only PUB_ID='05' I remove the "order by", the query takes only 3.5 seconds but I definitely have to return the ordered data and I would prefer to be able to filter several PUB_IDs
I thought the query could be improved if I removed the "inner join" from GROUP and changed the filter "glad.GROUP_TYPE ='3'" to "p.GROUP_CODE in ('01','07','10','21 ')" (these are all type 3 codes), because now it should use the IND_TABLE1_GROUP index but instead of improving, it gets worse, it takes 13 seconds even filtering only PUB_ID='05'; This is the plan that oracle generates:
------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 47 | 6251 | 172K| | |
| 1 | SORT ORDER BY | | 47 | 6251 | 172K| | |
| 2 | HASH JOIN | | 47 | 6251 | 172K| | |
| 3 | PARTITION RANGE ALL | | 47786 | 2613K| 82490 | 1 | 19 |
| 4 | PARTITION HASH ALL | | 47786 | 2613K| 82490 | 1 | 32 |
| 5 | TABLE ACCESS FULL | TABLE3 | 47786 | 2613K| 82490 | 1 | 608 |
| 6 | HASH JOIN | | 41945 | 3154K| 89633 | | |
| 7 | NESTED LOOPS | | 41945 | 3154K| 89633 | | |
| 8 | NESTED LOOPS | | 75740 | 3154K| 89633 | | |
| 9 | STATISTICS COLLECTOR | | | | | | |
| 10 | NESTED LOOPS | | 18935 | 924K| 15985 | | |
| 11 | TABLE ACCESS BY INDEX ROWID BATCHED | OFICE | 3 | 45 | 2 | | |
| 12 | INDEX RANGE SCAN | SYS_C0034405 | 3 | | 1 | | |
| 13 | INLIST ITERATOR | | | | | | |
| 14 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| TABLE1 | 6312 | 215K| 7039 | ROWID | ROWID |
| 15 | INDEX RANGE SCAN | IND_TABLE1_GROUP | 6828 | | 284 | | |
| 16 | INDEX RANGE SCAN | IND_TABLE2_REFNUM | 4 | | 2 | | |
| 17 | TABLE ACCESS BY INDEX ROWID | TABLE2 | 2 | 54 | 4 | | |
| 18 | INDEX FAST FULL SCAN | IND_TABLE2_QUERY | 2 | 54 | 2 | | |
------------------------------------------------------------------------------------------------------------------------------
And if I put all the PUB_IDs, Oracle generates this plan (it doesn't even use the IND_TABLE1_GROUP index anymore):
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 35661 | 4631K| 345K| | |
| 1 | SORT ORDER BY | | 35661 | 4631K| 345K| | |
| 2 | HASH JOIN | | 35661 | 4631K| 344K| | |
| 3 | TABLE ACCESS FULL | OFICE | 64 | 960 | 3 | | |
| 4 | HASH JOIN | | 35661 | 4109K| 344K| | |
| 5 | PARTITION RANGE ALL | | 1360K| 45M| 79580 | 1 | 19 |
| 6 | PARTITION HASH ALL | | 1360K| 45M| 79580 | 1 | 32 |
| 7 | TABLE ACCESS FULL | TABLE1 | 1360K| 45M| 79580 | 1 | 608 |
| 8 | HASH JOIN | | 2100K| 166M| 252K| | |
| 9 | NESTED LOOPS | | 2100K| 166M| 252K| | |
| 10 | STATISTICS COLLECTOR | | | | | | |
| 11 | PARTITION RANGE ALL | | 1681K| 89M| 82582 | 1 | 19 |
| 12 | PARTITION HASH ALL | | 1681K| 89M| 82582 | 1 | 32 |
| 13 | TABLE ACCESS FULL | TABLE3 | 1681K| 89M| 82582 | 1 | 608 |
| 14 | INDEX RANGE SCAN | IND_TABLE2_QUERY | 1 | 27 | 103K| | |
| 15 | INDEX FAST FULL SCAN | IND_TABLE2_QUERY | 32M| 845M| 103K| | |
-------------------------------------------------------------------------------------------------

Grouping fails when nesting data. How can I group this result by Unit?

How can I group this result by UnitMisnumber ?
Please see attached images of Data, Desired result and Current status.
I have hard time to use pivot and partition over, so I tested join and group, but I don't get desired result. Can anyone point me in the right direction? Below are the pictures of Data, Goal and Current Status.
Units are for selfdriving cars and they contain 2 cameras positioned Left and Right with an identifying number. Instead of Left on one row and right on next row, the goal is to show Left and Right as columns grouped by Unit.
Select #result.UnitMISNumber, t.CameraMISNumber [Left], x.CameraMISNumber [Right] from #result
left join (Select * from #result where Position = 'Left') t on t.CameraObjectID = #result.CameraObjectID
left join (Select * from #result where Position = 'Right') x on x.CameraObjectID = #result.CameraObjectID group by #result.UnitMISNumber, t.CameraMISNumber, x.CameraMISNumber
[Data]
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------+---------------+
| UnitMISNumber | CustomerSerialNumber | CameraTimestampCOTFT4A | CameraSerialNumber | CameraMISNumber | Position | ProductNumber |
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------+---------------+
| 6809930002020463005102 | 87501VC0002101040010 | 2020-11-1316:06:31.777 | 568802A020888D9A430BCC400000000 | 6465902002020372004505 | Left | 680993000H |
| 6809930002020463005102 | 87501VC0002101040010 | 2020-11-13 08:46:20.187 | 9ACDE222016B15A460227CA00000000 | 6465902002020372007710 | Right | 680993000H |
| 6809930002020477000101 | 87501VC0002101040040 | 2020-11-1719:04:41.730 | B40C0132D01E1E4662745E800000000 | 6465902002020454010709 | Left | 680993000H |
| 6809930002020477000101 | 87501VC0002101040040 | 2020-11-1811:33:54.533 | 064C4E8A66877204E251E69400000000 | 6465902002020454014407 | Right | 680993000H |
| 6809930002020484000204 | 87501VC0002101040020 | 2020-11-0520:54:47.060 | FB813AEE8D88F3584450CE9400000000 | 6465902002020433006201 | Left | 680993000H |
| 6809930002020484000204 | 87501VC0002101040020 | 2020-11-04 21:29:55.123 | 10304003850933B3E632A6EC00000000 | 6465902002020431008907 | Right | 680993000H |
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------+---------------+
[Desired]
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+------------+----------------------------------+------------------------+------------+
| 6809930002020463005102 | 87501V60002101040010 | 2020-11-13 16:06:31.777 | 568802A020888D9A430BCC400000000 | 6465902002020372004505 | 680993000H | 9ACDE222016B15A460227CA00000000 | 6465902002020372007710 | 680993000H |
| 6809930002020477000101 | 87501860002101040040 | 2020-11-17 19:04:41.730 | B40C0132D01E1E4662745E800000000 | 6465902002020454010709 | 680993000H | 064C4E8A66877204E251E69400000000 | 6465902002028454014407 | 680993000H |
| 6809930002020484000204 | 87501V60002101040020 | 2020-11-05 20:54:47.060 | FB813AEE8D88F3584450CE9400000000 | 6465902002020433006201 | 680993000H | 103D4003850933B3E632A6EC00000000 | 6465902002020431008907 | 680993000H |
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+------------+----------------------------------+------------------------+------------+
Data
Desired result
Current status
Here is how I might approach this.
You can run this example in SSMS:
DECLARE #Data table (
UnitMISNumber varchar(255),
CustomerSerialNumber varchar(255),
CameraTimestampCOTFT4A datetime,
CameraSerialNumber varchar(255),
CameraMISNumber varchar(255),
Position varchar(10),
ProductNumber varchar(50)
);
INSERT INTO #Data (
UnitMISNumber, CustomerSerialNumber, CameraTimestampCOTFT4A, CameraSerialNumber, CameraMISNumber, Position, ProductNumber
)
VALUES
( '6809930002020463005102', '87501VC0002101040010', '2020-11-13 16:06:31.777', '568802A020888D9A430BCC400000000', '6465902002020372004505', 'Left', '680993000H' ),
( '6809930002020463005102', '87501VC0002101040010', '2020-11-13 08:46:20.187', '9ACDE222016B15A460227CA00000000', '6465902002020372007710', 'Right', '680993000H' ),
( '6809930002020477000101', '87501VC0002101040040', '2020-11-17 19:04:41.730', 'B40C0132D01E1E4662745E800000000', '6465902002020454010709', 'Left', '680993000H' ),
( '6809930002020477000101', '87501VC0002101040040', '2020-11-18 11:33:54.533', '064C4E8A66877204E251E69400000000', '6465902002020454014407', 'Right', '680993000H' ),
( '6809930002020484000204', '87501VC0002101040020', '2020-11-05 20:54:47.060', 'FB813AEE8D88F3584450CE9400000000', '6465902002020433006201', 'Left', '680993000H' ),
( '6809930002020484000204', '87501VC0002101040020', '2020-11-04 21:29:55.123', '10304003850933B3E632A6EC00000000', '6465902002020431008907', 'Right', '680993000H ' );
SELECT
lft.UnitMISNumber,
lft.CustomerSerialNumber,
MAX ( lft.CameraTimestampCOTFT4A ) AS CameraTimestampCOTFT4A,
lft.CameraSerialNumber AS CameraSerialNumber_Left,
lft.CameraMISNumber AS CameraMISNumber_Left,
lft.ProductNumber AS CameraMISNumber_Left,
rgt.CameraSerialNumber_Right,
rgt.CameraMISNumber_Right,
rgt.ProductNumber_Right
FROM #Data AS lft
OUTER APPLY (
SELECT TOP 1
CameraSerialNumber AS CameraSerialNumber_Right,
CameraMISNumber AS CameraMISNumber_Right,
ProductNumber AS ProductNumber_Right
FROM #Data AS x WHERE
x.UnitMISNumber = lft.UnitMISNumber
AND x.Position = 'Right'
) AS rgt
WHERE
lft.Position = 'Left'
GROUP BY
lft.UnitMISNumber, lft.CustomerSerialNumber, lft.CameraSerialNumber, lft.CameraMISNumber, lft.ProductNumber,
rgt.CameraMISNumber_Right, rgt.CameraSerialNumber_Right, rgt.ProductNumber_Right
ORDER BY
UnitMISNumber;
Returns
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------------------+----------------------------------+------------------------+---------------------+
| UnitMISNumber | CustomerSerialNumber | CameraTimestampCOTFT4A | CameraSerialNumber_Left | CameraMISNumber_Left | CameraMISNumber_Left | CameraSerialNumber_Right | CameraMISNumber_Right | ProductNumber_Right |
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------------------+----------------------------------+------------------------+---------------------+
| 6809930002020463005102 | 87501VC0002101040010 | 2020-11-13 16:06:31.777 | 568802A020888D9A430BCC400000000 | 6465902002020372004505 | 680993000H | 9ACDE222016B15A460227CA00000000 | 6465902002020372007710 | 680993000H |
| 6809930002020477000101 | 87501VC0002101040040 | 2020-11-17 19:04:41.730 | B40C0132D01E1E4662745E800000000 | 6465902002020454010709 | 680993000H | 064C4E8A66877204E251E69400000000 | 6465902002020454014407 | 680993000H |
| 6809930002020484000204 | 87501VC0002101040020 | 2020-11-05 20:54:47.060 | FB813AEE8D88F3584450CE9400000000 | 6465902002020433006201 | 680993000H | 10304003850933B3E632A6EC00000000 | 6465902002020431008907 | 680993000H |
+------------------------+----------------------+-------------------------+----------------------------------+------------------------+----------------------+----------------------------------+------------------------+---------------------+

SQL Server: How to unpivot from pivoted table back to a self referencing table

I've looked at examples from: https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15 but I couldn't seem to find samples of what I'm trying to do.
I'm wondering if there's a way to unpivot from this:
+----+------------+--------+--------+--------+
| Id | Level0 | Level1 | Level2 | Level3 |
+----+------------+--------+--------+--------+
| 0 | TMI | | | |
+----+------------+--------+--------+--------+
| 1 | TMI | A | | |
+----+------------+--------+--------+--------+
| 2 | TMI | A | B | |
+----+------------+--------+--------+--------+
| 3 | TMI | A | B | C |
+----+------------+--------+--------+--------+
| 4 | TMI | A | B | D |
+----+------------+--------+--------+--------+
Back to self referencing table like this:
+----+-----------+----------+--------+
| Id | LevelName | ParentId | Level |
+----+-----------+----------+--------+
| 0 | TMI | | Level0 |
+----+-----------+----------+--------+
| 1 | A | 0 | Level1 |
+----+-----------+----------+--------+
| 2 | B | 1 | Level2 |
+----+-----------+----------+--------+
| 3 | C | 2 | Level3 |
+----+-----------+----------+--------+
| 4 | D | 2 | Level3 |
+----+-----------+----------+--------+

How to display "The Many" of a One-to-Many on One Line

I was provided 2 files, as two tables: 'VoterData' and 'VoterHistory' - What is the best way to accomplish my expected display?
EXPECTED DISPLAY
ID | First Name | Last Name | Election1 | Election2 | Election3
--------+------------+-------------+-----------+-----------+----------
2155077 | Camille | Bocchicchio | 2016June7 | 2016Nov8 | 2018June5
2155079 | Manabu | Lonny | 2016June7 | 2016Nov8 |
2155083 | Scott | Bosomworth | 2016June7 | | 2018June5
ONE- 'VoterData'
lVoterUniqueID | szNameFirst | szNameLast
---------------+-------------+------------
2155077 | Camille | Bocchicchio
2155079 | Manabu | Lonny
2155083 | Scott | Bosomworth
MANY- 'VoterHistory'
lVoterUniqueID | sElectionAbbr
---------------+---------------
2155077 | 2016June7
2155077 | 2016Nov8
2155077 | 2018June5
2155079 | 2016June7
2155079 | 2016Nov8
2155083 | 2016June7
2155083 | 2018June5
Using Crosstab query
TRANSFORM First(H.sElectionAbbr) AS FirstOfsElectionAbbr
SELECT H.lVoterUniqueID AS ID, D.szNameFirst AS [First Name], D.szNameLast AS [Last Name]
FROM VoterData AS D INNER JOIN VoterHistory AS H ON D.lVoterUniqueID = H.lVoterUniqueID
GROUP BY H.lVoterUniqueID, D.szNameFirst, D.szNameLast
PIVOT H.sElectionAbbr;

Values differences between days

I have a SQL Server 2005 table titled "Journeys" as follows:
+---------------+
| Journeys |
+---------------+
| JourneyID |
| PlateNumber |
| DepartureDate |
| DepartureKM |
| ArrivalDate |
| ArrivalKM |
+---------------+
The table contains the following sample data:
+------------+--------------+----------------+--------------+--------------+-----------+
| JOURNEYID | PLATENUMBER | DEPARTUREDATE | DEPARTUREKM | ARRIVALDATE | ARRIVALKM |
+------------+--------------+----------------+--------------+--------------+-----------+
| 1 | ABC-123 | 01-01-2015 | 10000 | 01-02-2015 | 10200 |
| 2 | ABC-123 | 01-02-2015 | 10210 | 01-03-2015 | 10500 |
| 3 | ABC-123 | 01-03-2015 | 10500 | 01-04-2015 | 10650 |
| 4 | ABC-123 | 01-04-2015 | 10607 | 01-05-2015 | 10900 |
| 5 | XYZ-999 | 01-15-2015 | 30200 | 01-16-2015 | 30400 |
| 6 | XYZ-999 | 01-16-2015 | 30405 | 01-17-2015 | 30600 |
| 7 | XYZ-999 | 01-17-2015 | 30600 | 01-18-2015 | 30750 |
| 8 | XYZ-999 | 01-18-2015 | 30752 | 01-19-2015 | 30920 |
+------------+--------------+----------------+--------------+--------------+-----------+
I want to generate a query that returns a the following results with an extra column named 'KMDifference' which is the difference between 'ArrivalKM' from last day and 'DepartureKM' from today.
Desired results:
+-------------+---------------+-------------+-------------+-----------+--------------+
| PlateNumber | DepartureDate | DepartureKM | ArrivalDate | ArrivalKM | KMDifference |
+-------------+---------------+-------------+-------------+-----------+--------------+
| ABC-123 | 01-01-2015 | 10000 | 01-02-2015 | 10200 | 0 |
| ABC-123 | 01-02-2015 | 10210 | 01-03-2015 | 10500 | 10 |
| ABC-123 | 01-03-2015 | 10500 | 01-04-2015 | 10650 | 0 |
| ABC-123 | 01-04-2015 | 10607 | 01-05-2015 | 10900 | 7 |
| XYZ-999 | 01-15-2015 | 30200 | 01-16-2015 | 30400 | 0 |
| XYZ-999 | 01-16-2015 | 30405 | 01-17-2015 | 30600 | 5 |
| XYZ-999 | 01-17-2015 | 30600 | 01-18-2015 | 30750 | 0 |
| XYZ-999 | 01-18-2015 | 30752 | 01-19-2015 | 30920 | 2 |
+-------------+---------------+-------------+-------------+-----------+--------------+
See this SQL Fiddle here: http://sqlfiddle.com/#!3/28abd
You can use the following CTE based query in order to simulate LAG function available from SQL Server 2012 onwards:
;WITH Journeys_rn AS (
SELECT JourneyID, PlateNumber, DepartureDate, DepartureKM, ArrivalDate, ArrivalKM,
ROW_NUMBER() OVER(PARTITION BY PlateNumber ORDER BY DepartureDate) AS rn
FROM Journeys
)
SELECT j1.PlateNumber, j1.DepartureDate, j1.DepartureKM,
j1.ArrivalDate, j1.ArrivalKM,
j1.DepartureKM - ISNULL(j2.ArrivalKM, j1.DepartureKM) AS KMDifference
FROM Journeys_rn AS j1
LEFT JOIN Journeys_rn AS j2 ON j1.rn = j2.rn+1 AND j1.PlateNumber = j2.PlateNumber
j2.ArrivalKM in the above query is the value from previous record. ISNULL is needed so that a 0 value is calculated for the first record of each group.
SQL Fiddle Demo
P.S. The sample data in the OP do not match with the sample data of the SQL Fiddle source also provided in the OP. So had to fix it in order to get the desired reult set.

Resources