Nested Case in SQL 2000 - sql

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

Related

Select groups given a condition in a variable sql

I must do a query where I select those groups, given by de concatenation between sample and serial that could be defined as household, where at least one in the variable bplcountry = 1
sample serial bplcountry
1 1 2
1 1 1
1 3 2
2 1 2
2 2 2
2 3 2
3 1 2
3 3 2
3 3 1
I have made some research but I'm very amateur on SQL. I get some hint like this:
SELECT *
FROM latinCensus
GROUP BY sample AND serial
HAVING COUNT(bplcountry NOT IN ('1') OR NULL) = 0
Also I got some idea in this way
SELECT *
FROM latinCensus
GROUP BY CONCAT(sample,serial)
HAVING COUNT(bplcountry NOT IN ('1') OR NULL) = 0
I would expect something like this:
sample serial bplcountry
1 1 2
1 1 1
3 3 2
3 3 1
I will appreciate your help!
You want the pairs where bplcountry is 1. You can use window functions:
select lc.*
from (select lc.*,
sum(case when bplcountry = 1 then 1 else 0 end) over (partition by sample, serial) as cnt_1
from latincensus lc
) lc
where cnt_1 > 0;
Or use exists:
select lc.*
from latincensus lc
where exists (select 1
from latincensus lc2
where lc2.sample = lc.sample and lc2.serial = lc.serial and
lc2.bplcountry = 1
);
You haven't tagged your db, but something along these lines should work (can also be expressed using joins)
select sample, serial, bplcountry
from t
where (sample,serial) in (select sample,serial
from t
where bplcountry=1);

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);

Best way to by column and aggregation on another column

I want to create a rank column using existing rank and binary columns. Suppose for example a table with ID, RISK, CONTACT, DATE. The existing rank is RISK, say 1,2,3,NULL, with 3 being the highest. The binary-valued is CONTACT with 0,1 or FAILURE/SUCESS. I want to create a new RANK that will order by RISK once a certain number of successful contacts has been exceeded.
For example, suppose the constraint is a minimum of 2 successful contacts. Then the rank should be created as follows in the two instances below:
Instance 1. Three ID, all have a min of two successful contacts. In that case the rank mirrors the risk:
ID risk contact date rank
1 3 S 1 3
1 3 S 2 3
1 3 F 3 3
1 3 F 4 3
2 2 S 1 2
2 2 S 2 2
2 2 F 3 2
2 2 F 4 2
3 1 S 1 1
3 1 S 2 1
3 1 S 3 1
Instance 2. Suppose ID=1 has only one successful contact. In that case it is relegated to the lowest rank, rank=1, while ID=2 gets the highest value, rank=3, and ID=3 maps to rank=2 because it satisfies the constraint but has a lower risk value than ID=2:
ID risk contact date rank
1 3 S 1 1
1 3 F 2 1
1 3 F 3 1
1 3 F 4 1
2 2 S 1 3
2 2 S 2 3
2 2 F 3 3
2 2 F 4 3
3 1 S 1 2
3 1 S 2 2
3 1 S 3 2
This is SQL, specifically Hive. Thanks in advance.
Edit - I think Gordon Linoff's code does it correctly. In the end, I used three interim tables. The code looks like that:
First,
--numerize risk, contact
select A.* ,
case when A.risk = 'H' then 3
when A.risk = 'M' then 2
when A.risk = 'L' then 1
when A.risk is NULL then NULL
when A.risk = 'NULL' then NULL
else -999 end as RISK_RANK,
case when A.contact = 'Successful' then 1
else NULL end as success
Second,
-- sum_successes_by_risk
select A.* ,
B.sum_successes_by_risk
from T as A
inner join
(select A.person, A.program, A.risk, sum(a.success) as sum_successes_by_risk
from T as A
group by A.person, A.program, A.risk
) as B
on A.program = B.program
and A.person = B.person
and A.risk = B.risk
Third,
--Create table that contains only max risk category
select A.* ,
B.max_risk_rank
from T as A
inner join
(select A.person, max(A.risk_rank) as max_risk_rank
from T as A
group by A.person
) as B
on A.person = B.person
and A.risk_rank = B.max_risk_rank
This is hard to follow, but I think you just want window functions:
select t.*,
(case when sum(case when contact = 'S' then 1 else 0 end) over (partition by id) >= 2
then risk
else 1
end) as new_risk
from t;

Group by clause with count() and where condition in subquery

Table : Class
id Institute_id Name
------------------------------
1 1 MCAL - 1
2 1 MCAL - 2
3 1 BCA - 1
4 1 BCA - 2
Table : Groups
id Class_Id Institute_Id Name Status
--------------------------------------------------
1 1 1 PHP false
2 2 1 JAVA false
3 1 1 ORACLE false
4 2 1 LINUX true
5 2 1 ASP.NET false
6 3 1 OS false
7 4 2 CPP false
Expected Result :
id Name Count(*)
-----------------------------
1 MCAL - 1 2
2 MCAL - 2 2
3 BCA - 1 1
4 BCA - 2 0
Note: count only those records from Groups where Institute_Id = 1 and Status=false
Please try this
Select
c.id,
c.name,
SUM(case when g.class_id is NULL then 0 else 1 end) as count
from class c left join groups g
on c.id=g.class_id
and g.status='false'
and g.Institute_id=1
group by c.id,c.name
order by c.id
fiddle link: http://sqlfiddle.com/#!6/2b992/6
To count properly with outer joins, specify the column name instead of * in COUNT().
SELECT C.id, C.Name, [Count] = COUNT(G.Status)
FROM Class C
LEFT JOIN Groups G ON C.id = G.Class_id AND G.Institute_id = 1 AND G.Status = 'false'
GROUP BY C.id, C.Name
ORDER BY C.id

Copying existing rows in a table

How do I go about doing the following?
I am using the following query to get a specific users tab ids:
select id
from intranet.dbo.tabs
where cms_initials = #user
order by id asc
which might return the following ids
4
5
6
7
I now want to insert the rows from the following query:
select tabs_id, widgets_id, sort_column, sort_row
from intranet.dbo.columns c
inner join intranet.dbo.tabs t on c.tabs_id = t.id
where t.is_default = 1
But use the ids from the first query to replace the tab ids
so if the second query originally returns tabs_id's as
0
0
0
0
1
1
1
2
2
2
3
3
I should end up with
0
0
0
0
1
1
1
2
2
2
3
3
4
4
4
4
5
5
5
6
6
6
7
7
Is this possible with sql server 2005 without using stored procedures?
So far I have
insert into intranet.dbo.columns ( tabs_id, widgets_id, sort_column, sort_row )
select tabs_id, widgets_id, sort_column, sort_row
from intranet.dbo.columns c
inner join intranet.dbo.tabs t on c.tabs_id = t.id
where t.is_default = 1
But this just copies everything as is, I need to do that, but replace the ids in the copied rows.
This solution uses common table expressions and ranking functions. A and B are your original queries ranked by tab order. A and B are then joined by tab ranking and inserted.
USE intranet
;WITH A AS
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS tab_ranking
, id
FROM dbo.tabs
WHERE cms_initials = #user
),
B AS
(
SELECT DENSE_RANK() OVER (ORDER BY tabs_id) AS tab_sequence
, tabs_id, widgets_id, sort_column, sort_row
FROM dbo.columns
WHERE tabs_id IN (SELECT t.id FROM dbo.tabs t WHERE t.is_default = 1)
)
INSERT INTO dbo.columns (tabs_id, widgets_id, sort_column, sort_row)
SELECT a.id, b.widgets_id, b.sort_column, b.sort_row
FROM A
INNER JOIN B ON B.tab_ranking = A.tab_ranking