Repeat Row Values - tsql
I have the following data:
with source (Account,AccountNumber,Indentation) as
(
select 'INCOME STATEMENT',1000,0 union all
select 'REVENUE',1100,0 union all
select 'Revenue - Aircon',1110,1 union all
select 'Revenue - Consumer Goods',1120,1 union all
select 'Revenue - Spares',1130,1 union all
select 'Revenue - Accessories',1140,1 union all
select 'Revenue - Sub Stock',1150,1 union all
select 'Revenue - Services',1160,1 union all
select 'Revenue - Other',1170,1 union all
select 'Revenue - Intercompany',1180,1 union all
select 'Revenue - Delivery Charges',1400,1 union all
select 'COST OF SALES',1500,0 union all
select 'COGS - Aircon',1510,1 union all
select 'COGS - Consumer Goods',1520,1 union all
select 'COGS - Spares',1530,1 union all
select 'COGS - Accessories',1540,1 union all
select 'COGS - Sub Stock',1550,1 union all
select 'COGS - Services',1560,1 union all
select 'COGS - Other',1570,1 union all
select 'COGS - Intercompany',1580,1 union all
select 'COS - Sub Stock Stock Adjustments',1610,1 union all
select 'COS - Sub Stock Repairs',1620,1 union all
select 'COS - Consumables & Packing Materials',1810,1 union all
select 'COS - Freight & Delivery',1820,1 union all
select 'COS - Inventory Adj - Stock Count',1910,1 union all
select 'COS - Inv. Adj - Stock Write up / Write down',1920,1 union all
select 'COS - Provision for Obsolete Stock (IS)',1930,1 union all
select 'COS - Inventory Adj - System A/c',1996,1 union all
select 'COS - Purch & Dir. Cost Appl A/c - System A/c',1997,1 union all
select 'GROSS MARGIN',1999,0 union all
select 'OTHER INCOME',2000,0 union all
select 'Admin Fees Received',2100,1 union all
select 'Bad Debt Recovered',2110,1 union all
select 'Discount Received',2120,1 union all
select 'Dividends Received',2130,1 union all
select 'Fixed Assets - NBV on Disposal',2140,1 union all
select 'Fixed Assets - Proceeds on Disposal',2145,1 union all
select 'Rebates Received',2150,1 union all
select 'Rental Income',2160,1 union all
select 'Sundry Income',2170,1 union all
select 'Warranty Income',2180,1 union all
select 'INTEREST RECEIVED',2200,0 union all
select 'Interest Received - Banks',2210,1
)
select
Account
, AccountNumber
, Indentation
from source;
Using the following script:
with s as (
select
iif(Account like 'Total%',null,iif(Indentation=0,Account,null)) Header
, iif(Account like 'Total%',null,iif(Indentation=1,Account,null)) SubHeader1
, *
from Source
)
select
Header
--, case lag(Header) over (order by [Account Number]) when Header then isnull(Header,lag(Header) over (order by [Account Number])) else Header end
, SubHeader1
, [Account Number]
, Indentation
from s
I'm able to split the columns like this:
I need to be able to report the Header Column to look like this:
I tried doing it using LAG(), but it doesn't work, how would I script this?
This is one option. I created a Group for each header and then used it to grab the first in that group that had an Indention = 0. Tack this on to your source CTE:
,CTE2 AS
(
select
iif(Account like 'Total%',null,iif(Indentation=0,Account,null)) Header
, iif(Account like 'Total%',null,iif(Indentation=1,Account,null)) SubHeader1
, SUM(CASE WHEN Indentation = 0 THEN 1 ELSE 0 END) OVER (ORDER BY AccountNUmber) H1
, *
from Source
)
SELECT T2.Header, t1.SubHeader1, t1.AccountNumber, t1.Indentation
FROM CTE2 t1
CROSS APPLY(SELECT MAX(t3.HEADER) HEADER FROM CTE2 T3 where t3.H1 = T1.H1 and T3.Indentation = 0 ) T2
ORDER BY t1.AccountNumber
Related
Update x column
How to update a specific column in stats table by using/amending the below mentioned script SELECT s.id, COUNT(t.val) AS count FROM stats s LEFT JOIN ( SELECT fir AS val FROM history UNION ALL SELECT sec FROM history UNION ALL SELECT thi FROM history UNION ALL SELECT fou FROM history UNION ALL SELECT fif FROM history UNION ALL SELECT six FROM history ) t ON s.id = t.val GROUP BY s.id;
According to Postgres documents You can use update query with from statement and use the result in set UPDATE stats u_s SET result = tmp_s.count FROM ( SELECT s.id, COUNT(t.val) AS count FROM stats s LEFT JOIN ( SELECT fir AS val FROM history UNION ALL SELECT sec FROM history UNION ALL SELECT thi FROM history UNION ALL SELECT fou FROM history UNION ALL SELECT fif FROM history UNION ALL SELECT six FROM history ) t ON s.id = t.val GROUP BY s.id ) tmp_s WHERE u_s.id = tmp_s.id;
Checking Slowly Changing Dimension 2
I have a table that looks like this: A slowly changing dimension type 2, according to Kimball. Key is just a surrogate key, a key to make rows unique. As you can see there are three rows for product A. Timelines for this product are ok. During time the description of the product changes. From 1-1-2020 up until 4-1-2020 the description of this product was ProdA1. From 5-1-2020 up until 12-2-2020 the description of this product was ProdA2 etc. If you look at product B, you see there are gaps in the timeline. We use DB2 V12 z/Os. How can I check if there are gaps in the timelines for each and every product? Tried this, but doesn't work with selectie (key, tel) as (select product, count(*) from PROD_TAB group by product having count(*) > 1) Select * from PROD_TAB A inner join selectie B on A.product = B.product Where not exists (SELECT 1 from PROD_TAB C WHERE A.product = C.product AND A.END_DATE + 1 DAY = C.START_DATE ) Does anyone know the answer?
The following query returns all gaps for all products. The idea is to enumerate (RN column) all periods inside each product by START_DATE and join each record with its next period record. WITH /* MYTAB (PRODUCT, DESCRIPTION, START_DATE, END_DATE) AS ( SELECT 'A', 'ProdA1', DATE('2020-01-01'), DATE('2020-01-04') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'A', 'ProdA2', DATE('2020-01-05'), DATE('2020-02-12') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'A', 'ProdA3', DATE('2020-02-13'), DATE('2020-12-31') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'B', 'ProdB1', DATE('2020-01-05'), DATE('2020-01-09') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'B', 'ProdB2', DATE('2020-01-12'), DATE('2020-03-14') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'B', 'ProdB3', DATE('2020-03-15'), DATE('2020-04-18') FROM SYSIBM.SYSDUMMY1 UNION ALL SELECT 'B', 'ProdB4', DATE('2020-04-16'), DATE('2020-05-03') FROM SYSIBM.SYSDUMMY1 ) , */ MYTAB_ENUM AS ( SELECT T.* , ROWNUMBER() OVER (PARTITION BY PRODUCT ORDER BY START_DATE) RN FROM MYTAB T ) SELECT A.PRODUCT, A.END_DATE + 1 START_DT, B.START_DATE - 1 END_DT FROM MYTAB_ENUM A JOIN MYTAB_ENUM B ON B.PRODUCT = A.PRODUCT AND B.RN = A.RN + 1 WHERE A.END_DATE + 1 <> B.START_DATE AND A.END_DATE < B.START_DATE; The result is: |PRODUCT|START_DT |END_DT | |-------|----------|----------| |B |2020-01-10|2020-01-11| May be more efficient way: WITH MYTAB2 AS ( SELECT T.* , LAG(END_DATE) OVER (PARTITION BY PRODUCT ORDER BY START_DATE) END_DATE_PREV FROM MYTAB T ) SELECT PRODUCT, END_DATE_PREV + 1 START_DATE, START_DATE - 1 END_DATE FROM MYTAB2 WHERE END_DATE_PREV + 1 <> START_DATE AND END_DATE_PREV < START_DATE;
Thnx Mark, will try this one of these days. Never heard of LAG in DB2 V12 for z/Os Will read about it Thnx
Oracle to Redshift query
I am trying to run below query and getting the error. ERROR: This type of correlated subquery pattern is not supported due to internal error. How can I re write subquery without altering the result. Highlighted in bold is causing the issue. SELECT bin_max, bin_count, ROUND(RATIO_TO_REPORT(bin_count) over (), 5) bin_percent FROM ( SELECT bin_max, cum_count - lag(cum_count, 1) over (ORDER BY bin_max) bin_count FROM ( SELECT b.bin_max, (select COUNT(*) FROM ndw_owner.MBP_USER_LOGINS_BY_USER ulbu WHERE ulbu.DAYS_SINCE_FIRST_LOGIN > 30 and ulbu.PROJECTED_30_DAY_LOGINS <= b.bin_max ) cum_count FROM (SELECT * FROM ( SELECT 1 AS BIN_MAX UNION SELECT 2 AS BIN_MAX UNION SELECT 3 AS BIN_MAX UNION SELECT 4 AS BIN_MAX UNION SELECT 5 AS BIN_MAX UNION SELECT 10 AS BIN_MAX UNION SELECT 15 AS BIN_MAX UNION SELECT 20 AS BIN_MAX UNION SELECT 30 AS BIN_MAX UNION SELECT 40 AS BIN_MAX UNION SELECT 60 AS BIN_MAX UNION SELECT 80 AS BIN_MAX UNION SELECT 99999999 AS BIN_MAX ) ) b ) );
Change the sub query to perform an inequality join between b and ulbu. This will make the data you need in the top query.
generate 10000 consecutive integers
Is there a better way to generate [0 ... 9999] than this: SELECT (a3.id + a2.id + a1.id + a0.id) id FROM ( SELECT 0 id UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) a0 CROSS JOIN ( SELECT 0 id UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90 ) a1 CROSS JOIN ( SELECT 0 id UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300 UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600 UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900 ) a2 CROSS JOIN ( SELECT 0 id UNION ALL SELECT 1000 UNION ALL SELECT 2000 UNION ALL SELECT 3000 UNION ALL SELECT 4000 UNION ALL SELECT 5000 UNION ALL SELECT 6000 UNION ALL SELECT 7000 UNION ALL SELECT 8000 UNION ALL SELECT 9000 ) a3 ORDER BY id Any feedback appreciated.
You could write it like this: ;WITH x as ( SELECT 0 id UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) SELECT row_number() over (order by (select 1))-1 id FROM x a0 CROSS JOIN x a1 CROSS JOIN x a2 CROSS JOIN x a3 By removing the order by you gained a little.
I am not sure why this answer was removed from POST, this also produced desired output ;WITH x as ( select id from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x(id) ) SELECT (a3.id * 1000 + a2.id * 100 + a1.id * 10 + a0.id) id FROM x a2 CROSS JOIN x a0 CROSS JOIN x a1 CROSS JOIN x a3
WITH a AS ( SELECT 0 AS a1 UNION ALL SELECT a1+1 FROM a WHERE a1+1<10000 ) SELECT * FROM a OPTION (Maxrecursion 10000)
How to transpose all rows into columns with particular column as header in sqlserver
I want to transpose each row of the table into different columns making one particular row as a header for the transposed table. Please help me out with this asap. Any simple example would be fine
Use PIVOT: select --userID, Stage1, Stage2, Stage3, Stage4 * from ( select '1' as UserID,'1' as Stage,'1-1-2013' as [Date] union all select '1','2','2-1-2013' union all select '2','1','1-1-2013' union all select '1','3','5-1-2013' union all select '2','2','3-1-2013' union all select '3','1','6-1-2013' union all select '3','2','8-1-2013' union all select '1','4','10-1-2013' union all select '3','3','12-1-2013' ) x pivot ( max([Date]) for Stage in ([1],[2],[3],[4],[5],[6]) ) p More about this topic: http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/