Value carry forword - sql

I have below SQL Query..
SELECT dbo.O3.[s.no] AS [O3_Sn.NO], dbo.O5.[s.no] AS [O5_Sn.NO], dbo.O3.O3, dbo.O5.O5,
case when dbo.O3.[s.no] > dbo.O5.[s.no] then 'true' else 'false' end as ComparisonColumn
FROM dbo.O3 INNER JOIN
dbo.O5 ON dbo.O3.[s.no] = dbo.O5.[s.no]
When I run I am getting below output..
O3_Sn.NO O5_Sn.NO O3 O5 ComparisonColumn
1 1 10 11 TRUE
2 2 12 13 TRUE
3 3 11 10 FALSE
4 4 13 11 FALSE
5 5 15 16 TRUE
6 6 10 11 TRUE
7 7 12 13 TRUE
I want to remember the value of TRUE / False and should ignore if it is repeated untill i get a reverse case i.e., for TRUE , False.. and FOR False .. TRUE
Below is the out i should get it..
O3_Sn.NO O5_Sn.NO O3 O5 ComparisonColumn New_Case_Carry_value
1 1 10 11 TRUE TRUE
2 2 12 13 TRUE NULL
3 3 11 10 FALSE FALSE
4 4 13 11 FALSE NULL
5 5 15 16 TRUE TRUE
6 6 10 11 TRUE NULL
7 7 12 13 TRUE NULL

You can order your output using row_number() to compare a value with a value of the previous record:
with cIntermediate as (
SELECT dbo.O3.[s.no] AS [O3_Sn.NO], dbo.O5.[s.no] AS [O5_Sn.NO], dbo.O3.O3, dbo.O5.O5,
case when dbo.O3.[s.no] > dbo.O5.[s.no] then 'true' else 'false' end
as ComparisonColumn,
rowno = row_number() over
(order by dbo.O3.[s.no], dbo.O5.[s.no], dbo.O3.O3, dbo.O5.O5)
FROM dbo.O3 INNER JOIN dbo.O5 ON dbo.O3.[s.no] = dbo.O5.[s.no]
)
select i1.*,
case when i1.ComparisonColumn = i2.ComparisonColumn then null
else i1.ComparisonColumn end as NewCaseCarryValue
from cIntermediate i1
left join cIntermediate i2 on i2.rowno=i1.rowno-1

Ok, I will explain the concept to you, and I am sure you will be able to figure it out for yourself.
Your final result you published with all the true and false columns, that needs to become a temporary table, like this, but with some kind of identity column:
SELECT dbo.o3.[s.no] AS [O3_Sn.NO]
,dbo.o5.[s.no] AS [O5_Sn.NO]
,dbo.o3.o3
,dbo.o5.o5
,CASE
WHEN dbo.o3.[s.no] > dbo.o5.[s.no] THEN 'true'
ELSE 'false'
END AS comparisoncolumn
, ROW_NUMBER() OVER(ORDER BY dbo.o3.[s.no]) AS ident_col
INTO #temp
FROM dbo.o3
INNER JOIN dbo.o5
ON dbo.o3.[s.no] = dbo.o5.[s.no]
Then what you need to do is to select from #temp, and self join to #temp in a similar manner as here:
SELECT a.*
, CASE WHEN a.comparisoncolumn = b.comparisoncolumn THEN NULL ELSE a.comparisoncolumn END AS final_comparisoncolumn
FROM #temp a
LEFT JOIN #temp b ON a.ident_col = b.ident_col - 1
Then do a case statement to figure out if you need to print null, or true or false.
Play around with this concept, I am sure you will be able to work it out from here.

You can do an left join on the table itself (SN = SN-1) and compare the ComparisonColumn

Related

Concatenate multiple rows to one big row

I have two tables in my database, with this sample data:
table 1: main
m_id eID sDate eDate
1 75 2022-12-01 NULL
table 2: details
m_id cc_id cu_id perc
1 1 1 40
1 1 2 40
1 1 3 20
Here's what I would like to achieve in SQL Server:
m_id eID sDate eDate cc_id^1 cu_id^1 perc^1 cc_id^2 cu_id^2 perc^2 cc_id^3 cu_id^3 perc^3
1 75 2022-12-01 NULL 1 1 40 1 2 40 1 3 20
So, the three rows in the 'details' table should be concatenated to the single row in the 'main' table.
I read about and tried the PIVOT Function, but I think it's not exactly what I'm looking for. To me, it seems PIVOT is using each unique value in the 'details' table as column header and then counts the number of instances of it. For example like this:
m_id eID sDate eDate 40
1 75 2022-12-01 NULL 2
So, basically using 40 as a column header and then fill its value with 2, as there are two instances of 40 in the perc column in the 'details' table.
I spent an entire day searching via Google and trying the PIVOT function without luck.
The only way I can think of it is this, (I would imagine that someone else will have a better solution!), BUT you NEED to know the values of [cu_id] ahead of time, and without knowing what the key is on Table 2, this is the best that I can do:
SELECT
Main.m_id,
Main.eID,
Main.sDate,
Main.eDate,
[Details1].[cc_id] AS [cc_id^1],
[Details1].[cu_id] AS [cu_id^1],
[Details1].[perc] AS [perc^1] ,
[Details2].[cc_id] AS [cc_id^2],
[Details2].[cu_id] AS [cu_id^2],
[Details2].[perc] AS [perc^2],
[Details3].[cc_id] AS [cc_id^3],
[Details3].[cu_id] AS [cu_id^3],
[Details3].[perc] AS [perc^3]
FROM [main] AS Main
INNER JOIN [Details] AS [Details1] ON Main.[m_id] = [Details1].[m_id]
INNER JOIN [Details] AS [Details2] ON Main.[m_id] = [Details1].[m_id]
INNER JOIN [Details] AS [Details3] ON Main.[m_id] = [Details3].[m_id]
WHERE
[Details1].[cu_id] = 1
AND
[Details2].[cu_id] = 2
AND
[Details3].[cu_id] = 3
I get the correct results, IF I know ahead of time what the values of cu_id are.
Many thanks for your help, Larnu and SWR!
#SWR unfortunately, the values for cu_id are not known ahead of time. They basically could be any integer. But thanks for your help though!
#Larnu, Thanks to you as well! I didn't post any of my pivot queries, as they got me nowhere near to the expected result. With the link to your other post, I was able to build this query.
WITH RNs AS(
SELECT h.clv_id, h.bed_id, h.wns_id, h.dvb_id, h.con_id, h.DateFrom, h.DateTo, d.kpl_id, d.kdr_id, d.dimension3, d.dimension4, d.dimension5, d.percentage
,ROW_NUMBER() OVER (PARTITION BY d.clv_id ORDER BY (SELECT NULL)) AS RN
FROM clv_hoofd h INNER JOIN clv_details d ON h.clv_id = d.clv_id
WHERE h.clv_id = 1094)
SELECT clv_id, bed_id, wns_id, dvb_id, con_id, DateFrom, DateTo,
CASE RN WHEN 1 THEN kpl_id END AS 'kpl^1',
CASE RN WHEN 1 THEN kdr_id END AS 'kdr^1',
CASE RN WHEN 1 THEN dimension3 END AS 'dim3^1',
CASE RN WHEN 1 THEN dimension4 END AS 'dim4^1',
CASE RN WHEN 1 THEN dimension5 END AS 'dim5^1',
CASE RN WHEN 1 THEN percentage END AS 'perc^1',
CASE RN WHEN 2 THEN kpl_id END AS 'kpl^2',
CASE RN WHEN 2 THEN kdr_id END AS 'kdr^2',
CASE RN WHEN 2 THEN dimension3 END AS 'dim3^2',
CASE RN WHEN 2 THEN dimension4 END AS 'dim4^2',
CASE RN WHEN 2 THEN dimension5 END AS 'dim5^2',
CASE RN WHEN 2 THEN percentage END AS 'perc^2',
CASE RN WHEN 3 THEN kpl_id END AS 'kpl^3',
CASE RN WHEN 3 THEN kdr_id END AS 'kdr^3',
CASE RN WHEN 3 THEN dimension3 END AS 'dim3^3',
CASE RN WHEN 3 THEN dimension4 END AS 'dim4^3',
CASE RN WHEN 3 THEN dimension5 END AS 'dim5^3',
CASE RN WHEN 3 THEN percentage END AS 'perc^3',
CASE RN WHEN 4 THEN kpl_id END AS 'kpl^4',
CASE RN WHEN 4 THEN kdr_id END AS 'kdr^4',
CASE RN WHEN 4 THEN dimension3 END AS 'dim3^4',
CASE RN WHEN 4 THEN dimension4 END AS 'dim4^4',
CASE RN WHEN 4 THEN dimension5 END AS 'dim5^4',
CASE RN WHEN 4 THEN percentage END AS 'perc^4',
CASE RN WHEN 5 THEN kpl_id END AS 'kpl^5',
CASE RN WHEN 5 THEN kdr_id END AS 'kdr^5',
CASE RN WHEN 5 THEN dimension3 END AS 'dim3^5',
CASE RN WHEN 5 THEN dimension4 END AS 'dim4^5',
CASE RN WHEN 5 THEN dimension5 END AS 'dim5^5',
CASE RN WHEN 5 THEN percentage END AS 'perc^5',
CASE RN WHEN 6 THEN kpl_id END AS 'kpl^6',
CASE RN WHEN 6 THEN kdr_id END AS 'kdr^6',
CASE RN WHEN 6 THEN dimension3 END AS 'dim3^6',
CASE RN WHEN 6 THEN dimension4 END AS 'dim4^6',
CASE RN WHEN 6 THEN dimension5 END AS 'dim5^6',
CASE RN WHEN 6 THEN percentage END AS 'perc^6'
FROM RNs R
This returns six rows, doing it like this:
kpl_id^1 kdr_id^1 dimension3^1 dimension4^1 dimension5^1 percentage^1 kpl_id^2 kdr_id^2 dimension3^2 dimension4^2 dimension5^2 percentage^2
2 1 00000 01 NVT 50.00 NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL 1 1 00000 02 NVT 10.00
...
This query comes from my real world database, hence the different names for tables and columns.
Thanks in advance!

Facing problem with case when statement in a single row fetch for oracle sql

I have a single row of data as follows:
dyn1 dyn2 dyn3 chg
1 0 1 768
Now i want to write a case condition like
Case when dyn1 = 1 then 7 When dyn2=1 then 7 When dyn3=1 then 7 End
Now for this above records it is not checking the dyn3 value as it is getting dyn1 value as true.
How to handle this code?
I'll suppose that you need to return those values in a select statement, maybe this could be helpful to you.
SELECT CASE WHEN dyn1 = 1 THEN 7 END,
CASE WHEN dyn2 = 1 THEN 7 END,
CASE WHEN dyn3 = 1 THEN 7 END
FROM (SELECT 1 AS dyn1, 1 AS dyn2, 1 AS dyn3 FROM dual);
Or, maybe you want it in an only column
SELECT CASE WHEN dyn1 = 1 THEN 7 END ||
CASE WHEN dyn2 = 1 THEN 7 END ||
CASE WHEN dyn3 = 1 THEN 7 END
from (select 1 as dyn1, 1 as dyn2, 1 as dyn3 from dual);

SQL: combining two sql queries

I have two tables:
T_CHAMBRE_CHB (CHB_NUM);
T_PLANNING_PLN (PLN_JOUR ,CHB_NUM, PLN_LIBRE);
I have these values in it:
T_CHAMBRE_CHB:
1
2
3
4
T_PLANNIG_CHB:
1 2000-01-12 1 False
2 2000-01-12 2 False
3 2000-01-13 1 False
4 2000-01-13 2 False
5 2000-01-13 4 True
I would like to get the rooms occpation the 13 janvier 2000 for information if a room is not in the planning (here 3) that's mean it's free, so the result should be:
CHB_NUM PLN_LIBRE
----------- ---------
1 False
2 False
3 True
4 True
I have this query:
SELECT DISTINCT TCC.CHB_NUM, TPP.PLN_LIBRE
FROM T_CHAMBRE_CHB AS TCC,
T_PLANNING_PLN AS TPP
WHERE TCC.CHB_NUM=TPP.CHB_NUM AND TPP.PLN_JOUR = '2000-01-13'
UNION
SELECT DISTINCT TCC.CHB_NUM, TPP.PLN_LIBRE
FROM T_CHAMBRE_CHB AS TCC,
T_PLANNING_PLN AS TPP
WHERE TCC.CHB_NUM NOT IN (SELECT DISTINCT (TPP2.CHB_NUM) FROM T_PLANNING_PLN AS TPP2);
I get this result:
1 1 False
2 2 False
3 3 False
4 3 True
5 4 True
I don't know why I get the third line ( 3---->False )
I think I should use an OUTER UNION but SQL Server doesn't like the syntax.
Below query might give the required result :-
declare #date as date='2000-01-13'
select distinct TCC.CHB_NUM,COALESCE(TPP.PLN_JOUR,#date) PLN_JOUR,COALESCE(TPP.PLN_LIBRE,'True') PLN_LIBRE
from T_CHAMBRE_CHB TCC
LEFT OUTER JOIN
T_PLANNING_PLN TPP ON TCC.CHB_NUM=TPP.CHB_NUM
WHERE TPP.PLN_JOUR=#date OR TPP.PLN_JOUR IS NULL
Output :-
CHB_NUM PLN_JOUR PLN_LIBRE
1 2000-01-13 False
2 2000-01-13 False
3 2000-01-13 True
4 2000-01-13 True
You have to use left join if I am understanding your question.
Please use below query may be it helps you
SELECT T_CHAMBRE_CHB.CHB_NUM, ISNULL(T_PLANNIG_CHB.PLN_LIBRE, FALSE)
FROM T_CHAMBRE_CHB
LEFT JOIN T_PLANNIG_CHB ON (T_CHAMBRE_CHB.CHB_NUM = T_PLANNIG_CHB.CHB_NUM)
WHERE T_PLANNIG_CHB.PLN_JOUR = '2000-01-13'

Nested Case in SQL 2000

I have the following SQL statement, when executing it on SQL 2008 it works perfectly with no problem. But when excuted in SQL 2000 it says:
Internal SQL Server error
I think the problem comes because of using nested case statement in SQL 2000. Here is the SQL statement:
WHEN 14 THEN
Case When (select COUNT(*) from [dbo].[mnrFnBI_Fixed](#CurrencyID) f where f.BAccCustID!=0x0 AND f.biMatID = bi.biMatID)>0 THEN
CASE (select top 1 PriceType from (select top 1 f.BDate,f.BNumber , tc.PriceType From [dbo].[mnrFnBI_Fixed](#CurrencyID) f inner join #tcust tc on tc.AccID = f.BAccCustID AND tc.PriceType!=0 Where f.biMatID =bi.biMatID AND f.BAccCustID != 0x0 order by f.BDate desc,f.BNumber desc ) as k) -- Price From customer Card
WHEN 1 THEN
CASE #UseUnit WHEN 1 THEN mtEndUser1
WHEN 2 THEN mtEndUser2
WHEN 3 THEN mtEndUser3
WHEN 4 THEN mtEndUser4
WHEN 5 THEN mtEndUser5
WHEN 0 THEN CASE [mtDefUnit] WHEN 1 THEN mtEndUser1
WHEN 2 THEN mtEndUser2
WHEN 3 THEN mtEndUser3
WHEN 4 THEN mtEndUser4
WHEN 5 THEN mtEndUser5
END
END
---*******************---
WHEN 2 THEN
CASE #UseUnit WHEN 1 THEN mtWhole1
WHEN 2 THEN mtWhole2
WHEN 3 THEN mtWhole3
WHEN 4 THEN mtWhole4
WHEN 5 THEN mtWhole5
WHEN 0 THEN CASE [mtDefUnit] WHEN 1 THEN mtWhole1
WHEN 2 THEN mtWhole2
WHEN 3 THEN mtWhole3
WHEN 4 THEN mtWhole4
WHEN 5 THEN mtWhole5
END
END
---*******************---
END
END
When I remove the part between the '*****' it works perfectly !
Please tell me how case statement works with SQL 2000 ?!
Update :
when change the above code to :
WHEN 14 THEN
Case
WHEN (select COUNT(*) from [dbo].[mnrFnBI_Fixed](#CurrencyID) f where f.BAccCustID!=0x0 AND f.biMatID = bi.biMatID)>0 THEN
case
when (select top 1 PriceType from (select top 1 f.BDate,f.BNumber , tc.PriceType From [dbo].[mnrFnBI_Fixed](#CurrencyID) f inner join #tcust tc on tc.AccID = f.BAccCustID AND tc.PriceType!=0 Where f.biMatID =bi.biMatID AND f.BAccCustID != 0x0 order by f.BDate desc,f.BNumber desc ) as k) =1 THEN
CASE #UseUnit WHEN 1 THEN mtEndUser1
WHEN 2 THEN mtEndUser2
WHEN 3 THEN mtEndUser3
WHEN 4 THEN mtEndUser4
WHEN 5 THEN mtEndUser5
WHEN 0 THEN CASE [mtDefUnit] WHEN 1 THEN mtEndUser1
WHEN 2 THEN mtEndUser2
WHEN 3 THEN mtEndUser3
WHEN 4 THEN mtEndUser4
WHEN 5 THEN mtEndUser5
END
END
when(select top 1 PriceType from (select top 1 f.BDate,f.BNumber , tc.PriceType From [dbo].[mnrFnBI_Fixed](#CurrencyID) f inner join #tcust tc on tc.AccID = f.BAccCustID AND tc.PriceType!=0 Where f.biMatID =bi.biMatID AND f.BAccCustID != 0x0 order by f.BDate desc,f.BNumber desc ) as k) = 2 THEN
CASE #UseUnit WHEN 1 THEN mtWhole1
WHEN 2 THEN mtWhole2
WHEN 3 THEN mtWhole3
WHEN 4 THEN mtWhole4
WHEN 5 THEN mtWhole5
WHEN 0 THEN CASE [mtDefUnit] WHEN 1 THEN mtWhole1
WHEN 2 THEN mtWhole2
WHEN 3 THEN mtWhole3
WHEN 4 THEN mtWhole4
WHEN 5 THEN mtWhole5
END
END
END
END
it works , so please tell what's wrong with the first Sql Commands in sql 2000 ?!
This example can Help You.
UPDATE table_name
SET column_name=CASE
WHEN column_name in ('value1', 'value2',.....)
THEN 'update_value'
WHEN column_name in ('value1', 'value2',.....)
THEN 'update_value'
END

sql server count distinct value of a field

I have 2 tables : Contents and Packs
In Content columns are like this:
Id Name IsPerishable IsSpecial IsDanger
----------------------------------------------------------
1 Paper False False False
3 Fruit True False False
5 NewsPaper False True False
6 Radioactive False False True
7 Foods True False False
In Packs columns are like this:
Id From To ContentId
---------------------------------------
1 ABZ ATL 3
2 ANU ATL 5
3 BAQ ATL 7
4 BTS BAQ 6
5 FRL BAQ 5
Now I want a result that groups every 'To' then shows separate value of IsPerishable / IsSpecial / IsDanger
like this:
To Perishable Special Danger
-----------------------------------------------
ATL 2 1 0
BAQ 0 1 1
I try use some query but none of them has worked correctly:
select Name,
case
when IsSpecial = 1 then count(IsSpecial)
when IsPerishable = 1 then count(IsPerishable)
when IsDanger = 1 then count(IsDanger)
end as 'Content'
from Contents
group by IsSpecial , IsPerishable , IsDanger
select To,count(DISTINCt Id) as 'Count'
FROM Packs
GROUP BY To
try this
Select To,
(Select count(*) from Content c where c.Id= p.Id and c.IsSpecial=1) as Special,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Perishable,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Danger
from
pack p
group by To
SELECT P.To, SUM(Perishable), SUM(Special),SUM(Danger) FROM
(
SELECT Id,
CASE IsPerishable WHEN true THEN 1 ELSE 0 END AS Perishable,
CASE IsSpecial WHEN true then 1 ELSE 0 END AS Special,
CASE IsDanger WHEN true then 1 ELSE 0 END AS Danger
FROM Contents
) C
Right Join Packs P
on P.ContentId=C.Id
Group BY P.to