Multiple And Statements - sql

I am trying to identify when a record has AtAboveBelowGradeLevel = 1 for both years. In other words, how would I do case the case statement below?
SELECT AcademicYear
,SchoolName
,Subject
,LastName
,firstname
,StudentBKID
,AtAboveBelowGradeLevelCount
,CASE
WHEN AtAboveBelowGradeLevelCount = 1
AND AcademicYear = '2015-2016'
AND AcademicYear = '2016-2017'
AND AtAboveBelowGradeLevelCount = 1
THEN 'TRUE'
ELSE 'NO'
END
FROM StudentAssessmentMart.dbo.vwMAPAssessmentInformation
WHERE AcademicYear IN (
'2015-2016'
,'2016-2017'
)
AND SchoolName LIKE 'alliance%'
AND subject IN ('math')
AND StudentBKID IN (
'473106'
,'420219'
)
AND CalendarPeriodName = 'spring'
GROUP BY AcademicYear
,SchoolName
,Subject
,LastName
,firstname
,StudentBKID
,AtAboveBelowGradeLevelCount
ORDER BY StudentBKID
,AcademicYear

this is a simplify version
SELECT
StudentBKID
,CASE
WHEN COUNT(CASE WHEN AtAboveBelowGradeLevelCount = 1 THEN 1 END) = 2
THEN 'TRUE'
ELSE 'NO'
END
FROM StudentAssessmentMart.dbo.vwMAPAssessmentInformation
WHERE AcademicYear IN ('2015-2016','2016-2017')
AND SchoolName LIKE 'alliance%'
AND subject IN ('math')
AND StudentBKID IN ('473106','420219')
AND CalendarPeriodName = 'spring'
GROUP BY StudentBKID
The Year is already filter on the WHERE, so you only need a conditional counting so see how many of those are AboveBelowGrade

Related

Need help to simplify this T-SQL query

I have this working T-SQL query, is there any way to simplify it?
The SELECT COUNT(*) FROM Tablename is repeating and only the condition is different for each query, so is there a way to simplify this more? thank you
SELECT COUNT(*) FROM Table
WHERE columnA = 'I' AND columnB = 'I' AND columnC =''
UNION ALL
SELECT COUNT(*) FROM Table
WHERE columnA = 'I' AND columnB = 'I' AND columnC <>''
UNION ALL
SELECT COUNT(*) FROM Table
WHERE columnA IN ('A','R') AND columnB = 'I' AND columnD IN (SELECT columnE FROM Table2)
UNION ALL
SELECT COUNT(*) FROM Table
WHERE columnA IN ('B') AND columnB = 'I'
UNION ALL
SELECT COUNT(*) FROM Table
WHERE columnA IN ('R') AND columnB = 'S'
UNION ALL
SELECT COUNT(*) FROM Table
WHERE columnA IN ('A') AND columnB = 'S'
This is the working query and my output is 6 rows, want to maintain that
Let me assume that BI_BRH is unique in STDHOST. This is not strictly necessary but it are simplifying.
Then you can use conditional aggregation. I think putting the values in columns is the simplest approach:
SELECT SUM(CASE WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO = '' THEN 1 ELSE 0 END),
SUM(CASE WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO <>'' THEN 1 ELSE 0 END)
SUM(CASE WHEN STATUS IN ('A','R') AND TRX_STATE = 'I' AND s.BI_BRH IS NOT NULL THEN 1 ELSE 0 END)
SUM(CASE WHEN STATUS IN ('B') AND TRX_STATE = 'I' THEN 1 ELSE 0 END)
SUM(CASE WHEN STATUS IN ('R') AND TRX_STATE = 'S' THEN 1 ELSE 0 END)
SUM(CASE WHEN STATUS IN ('A') AND TRX_STATE = 'S' THEN 1 ELSE 0 END)
FROM ICSCHQINFO i LEFT JOIN
STDHOST s
ON s.BI_BRH = i.BRH_ASSIGN_TO;
Your code runs 6 times over the same table, with different conditions in the WHERE clause and returns 6 rows.
Assuming that the 6 conditions you have are mutually exclusive, you can create a CTE that returns for each row the category that it belongs to and then aggregate on that category:
WITH cte AS (
SELECT CASE
WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO = '' THEN 'cat1'
WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO <> '' THEN 'cat2'
WHEN STATUS IN ('A','R') AND TRX_STATE = 'I' AND BRH_ASSIGN_TO IN (SELECT BI_BRH FROM STDHOST) THEN 'cat3'
WHEN STATUS IN ('B') AND TRX_STATE = 'I' THEN 'cat4'
WHEN STATUS IN ('R') AND TRX_STATE = 'S' THEN 'cat5'
WHEN STATUS IN ('A') AND TRX_STATE = 'S' THEN 'cat6'
END category
FROM ICSCHQINFO
)
SELECT category, COUNT(*) counter
FROM cte
GROUP BY category
If there are no rows for any of the categories and in that case you want a row with 0, you need another CTE that returns the categories and LEFT join to the other CTE:
WITH
categories AS (SELECT category FROM (VALUES ('cat1'), ('cat2'), ('cat3'), ('cat4'), ('cat5'), ('cat6')) v(category)),
cte AS (
SELECT CASE
WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO = '' THEN 'cat1'
WHEN STATUS = 'I' AND TRX_STATE = 'I' AND ASSIGN_TO <> '' THEN 'cat2'
WHEN STATUS IN ('A','R') AND TRX_STATE = 'I' AND BRH_ASSIGN_TO IN (SELECT BI_BRH FROM STDHOST) THEN 'cat3'
WHEN STATUS IN ('B') AND TRX_STATE = 'I' THEN 'cat4'
WHEN STATUS IN ('R') AND TRX_STATE = 'S' THEN 'cat5'
WHEN STATUS IN ('A') AND TRX_STATE = 'S' THEN 'cat6'
END category
FROM ICSCHQINFO
)
SELECT c.category, COUNT(t.category) counter
FROM categories c LEFT JOIN cte t
ON t.category = c.category
GROUP BY c.category

T-SQL - how do I get this result set

how do I get the following result set...
Desc0, Desc1, ,Desc2 ,Desc3 , Desc4
ASSETS,Fixed Assets,Tangible Fixed Assets,Land and Buildings, Equipment
ASSETS,Fixed Assets,Tangible Fixed Assets,Vehicles , Null
if the source table looks like this...
Desc, type
ASSETS, 0
Fixed Assets, 1
Tangible Fixed Assets, 2
Land and Buildings, 3
Operating Equipment 4,
Vehicles, 3
I tried this...
`SELECT case when type=0 then Name else null end report_type,
case when type=1 then Name else null end account_level_1,
case when type=2 then Name else null end account_level_2,
case when type=3 then Name else null end account_level_3,
case when type=4 then Name else null end account_level_4,
case when type=5 then Name else null end account_level_5
from [dbo].[Account]`
You want a row_number() & do conditional aggregation :
select max(case when [type] = 0 then [desc] end),
max(case when [type] = 1 then [desc] end),
max(case when [type] = 2 then [desc] end),
max(case when [type] = 3 then [desc] end)
from (select a.*,
row_number() over (partition by [type] order by [desc]) as seq
from [dbo].[Account] a
) a
group by seq;

Subqueries in MSSQL producing NULL values

I am trying to determine my store only accounts revenue from the database, to do this I need to look through all account numbers with revenue against a 'store' description who do NOT appear in a list of accounts with an 'online' description which I have tried todo in the subquery below. The query runs however it just returns NULL values in my store_only_revenue column. Any guidance on what to do from here would be appreciated. Am I approaching the problem in a good way? Or is there a better solution:
SELECT
town,
financial_pd as month,
SUM(CASE WHEN [Descr] = 'online' THEN Net_Revenue ELSE 0 END) as online_revenue,
SUM(CASE WHEN [Descr] = 'store' THEN Net_Revenue ELSE 0 END) as store_revenue,
COUNT(DISTINCT CASE WHEN [Descr] = 'online' THEN Account_Number ELSE NULL END) as online_accounts,
COUNT(DISTINCT CASE WHEN [Descr] = 'store' THEN Account_Number ELSE NULL END) as store_accounts,
(SELECT
SUM(Net_Revenue)
FROM [mydb].[dbo].[mytable]
WHERE
Descr = 'store'
AND Account_Number
NOT IN(
SELECT DISTINCT Account_Number
FROM [mydb].[dbo].[mytable]
WHERE
Descr = 'online')
) as store_only_revenue
FROM [mydb].[dbo].[mytable] as orders
WHERE
Group_name = 'T'
AND NOT
Type_name_1 = 'Electronic'
AND
Account_type <> 1
AND
Total_Value > 0
AND
(Insert_Date BETWEEN '2016-05-30' AND '2016-07-03'
OR
Insert_Date BETWEEN '2015-05-25' AND '2015-06-28')
OR
(Insert_Date BETWEEN '2016-05-30' AND '2016-07-03'
AND
Insert_Date BETWEEN '2015-05-25' AND '2015-06-28')
GROUP BY
town,
financial_pd as period
This expression is suspect:
Account_Number NOT IN (SELECT DISTINCT t.Account_Number
FROM [mydb].[dbo].mytable t
WHERE t.Descr = 'online'
)
Assuming that the syntax problems are typos (missing table name, desc is a reserved word), then this will never return true if even one Account_Number is NULL. One way to fix this is:
Account_Number NOT IN (SELECT t.Account_Number
FROM [mydb].[dbo].mytable t
WHERE t.Desc = 'online' AND t.Account_Number IS NOT NULL
)
I would use NOT EXISTS:
not exists (select 1
from [mydb].[dbo].??? x
where x.Desc = 'online' AND ??.Account_Number = x.Account_Number
)
You need to use proper table aliases for this to work. Either of these solutions may fix your problem.

counting records on the same table with different values possibly none sql server 2008

I have a inventory table with a condition i.e. new, used, other, and i am query a small set of this data, and there is a possibility that all the record set contains only 1 or all the conditions. I tried using a case statement, but if one of the conditions isn't found nothing for that condition returned, and I need it to return 0
This is what I've tried so far:
select(
case
when new_used = 'N' then 'new'
when new_used = 'U' then 'used'
when new_used = 'O' then 'other'
end
)as conditions,
count(*) as count
from myDB
where something = something
group by(
case
when New_Used = 'N' then 'new'
when New_Used = 'U' then 'used'
when New_Used = 'O' then 'other'
end
)
This returns the data like:
conditions | count
------------------
new 10
used 45
I am trying to get the data to return like the following:
conditions | count
------------------
new | 10
used | 45
other | 0
Thanks in advance
;WITH constants(letter,word) AS
(
SELECT l,w FROM (VALUES('N','new'),('U','used'),('O','other')) AS x(l,w)
)
SELECT
conditions = c.word,
[count] = COUNT(x.new_used)
FROM constants AS c
LEFT OUTER JOIN dbo.myDB AS x
ON c.letter = x.new_used
AND something = something
GROUP BY c.word;
try this -
DECLARE #t TABLE (new_used CHAR(1))
INSERT INTO #t (new_used)
SELECT t = 'N'
UNION ALL
SELECT 'N'
UNION ALL
SELECT 'U'
SELECT conditions, ISNULL(r.cnt, 0) AS [count]
FROM (
VALUES('U', 'used'), ('N', 'new'), ('O', 'other')
) t(c, conditions)
LEFT JOIN (
SELECT new_used, COUNT(1) AS cnt
FROM #t
--WHERE something = something
GROUP BY new_used
) r ON r.new_used = t.c
in output -
new 2
used 1
other 0
You can do it as a cross-tab:
select
sum(case when new_used = 'N' then 1 else 0 end) as N,
sum(case when new_used = 'U' then 1 else 0 end) as U,
sum(case when new_used = 'O' then 1 else 0 end) as Other
from myDB
where something = something

SQL select display row data as columns for varchar items

This is the query I am using to generate my table:
SELECT cu.idchanneluser AS Approver,
mcr.idrule AS Rule,
mrd.idseq AS Seq,
mcr.idcust AS CustID,
cu.iduser AS USERID
FROM mstchanneluser cu,
mstcatruledetail mrd,
mstcatrule mcr
WHERE idchannel='01'
AND mrd.idlist=cu.iduser
AND mrd.idrule=mcr.idrule
AND mcr.nbrauth='2'
AND mcr.isautoauth='N'
and this the snapshot of result:
but I want result like this:
FirstAuthorizer SecondAuthorzier Rule
rohitcorp ajitcorp 3090
CORPTEST TESTCORP 8634
ABHIMAKER CORPTEST 11705
I tried this query:
SELECT CASE WHEN idseq = '0' THEN idchanneluser ELSE NULL END AS Approver,
case when idseq = '1' THEN idchanneluser ELSE NULL END AS secondApprover,
cu.idchanneluser AS Approver,
mcr.idrule AS Rule,
mrd.idseq AS Seq,
mcr.idcust AS CustID,
cu.iduser AS USERID
FROM mstchanneluser cu,
mstcatruledetail mrd,
mstcatrule mcr
WHERE idchannel='01'
AND mrd.idlist=cu.iduser
AND mrd.idrule=mcr.idrule
AND mcr.nbrauth='2'
AND mcr.isautoauth='N'
and it will be returning me this result check the snapshot.
this is derived from your second query, you just need to use MAX and group them by mcr.idrule
SELECT MAX(CASE WHEN idseq = '0' THEN idchanneluser ELSE NULL END) AS Approver
, MAX(CASE WHEN idseq = '1' THEN idchanneluser ELSE NULL END) AS secondApprover
, mcr.idrule AS RULE
FROM mstchanneluser cu
, mstcatruledetail mrd
, mstcatrule mcr
WHERE idchannel = '01'
AND mrd.idlist = cu.iduser
AND mrd.idrule = mcr.idrule
AND mcr.nbrauth = '2'
AND mcr.isautoauth = 'N'
GROUP BY mcr.idrule
Another way in oracle with Analytical function lead lag
select tab.y FirstAuthorizer,tab.x SecondAuthorzier,tab.rule from
(
select lead(appprover,0) over (partition by rule order by seq) x ,
lag(appprover,1) over (partition by rule order by seq) y,
rule
from tbl ) tab
where tab.y is not null;