Subquery in CTE - sql-server

i'm trying to get the status of student after the semester ends
and then update the status in it's table
can i use subquery inside the CTE ??
;with temp As
(
select CASE WHEN Status = 0 then 'Passed'
when status >0 and status < 2 then 'uncomplete'
else 'Failed' end Studentstatus
from
(
SELECT StudentID,
sum(CASE WHEN CourseStatus =1 then 1 else 0 end) Status
FROM StudentFinalResultsDetails
group by StudentID
)As t
)--the error in this line
the problem is
Incorrect syntax near ')'

You don't need a subquery for this, either use a CTE or subquery; you are mixing both of them, just do this:
with temp As
(
SELECT StudentID,
sum(CASE WHEN CourseStatus =1 then 1 else 0 end) Status
FROM StudentFinalResultsDetails
group by StudentID
) -- You have to select something after the brackets
select CASE WHEN Status = 0 then 'Passed'
when status >0 and status < 2 then 'uncomplete'
else 'Failed' end AS Studentstatus
from temp
Or: remove WITH CTE:
select CASE WHEN Status = 0 then 'Passed'
when status >0 and status < 2 then 'uncomplete'
else 'Failed' end Studentstatus
from
(
SELECT StudentID,
sum(CASE WHEN CourseStatus =1 then 1 else 0 end) Status
FROM StudentFinalResultsDetails
group by StudentID
)As t
Update
The problem in the query in your question, you have to move the part:
select CASE WHEN Status = 0 then 'Passed'
when status >0 and status < 2 then 'uncomplete'
else 'Failed' end AS Studentstatus`
to the outer of the brackets of the WITH temp ( .... ) then after it select whatever you want from it.
Because:
A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE
statement that references some or all the CTE columns. A CTE can also
be specified in a CREATE VIEW statement as part of the defining SELECT
statement of the view.
In your query, you didn't put any statements after it. See reference

Related

select distinct with parent-child and return boolean for at least one child with a value?

I am currently searching for orders that have at least one orderline (product) with a certain boolean set:
- the product is a subscription product
- the product is a setup product
If one of the orderlines has this value set to 1, I want to return this in the query per DISTINCT order ID.
This does not seem to work for me:
SELECT DISTINCT [ORDER].[order_id]
,[ORDERLINE].[is_subscription] AS hasSubArticles
,[ORDERLINE].[is_setup] AS hasSetupArticles
FROM [ORDER]
LEFT JOIN [ORDERLINE]
ON [ORDER].[order_id] = [ORDERLINE].[f_order_id]
WHERE [G_ORDER].[status] = 1
ORDER BY [ORDER].[order_id]
,[ORDERLINE].[is_subscription] AS hasSubArticles
,[ORDERLINE].[is_setup] AS hasSetupArticles
When I check the returned records, I receive duplicate ORDER records:
order_id hasSubArticles hasSetupArticles
----------------------------------------
17804 NULL NULL
17804 1 0
I want to return only 1 record per order ID, thus this isn't working for me.
What am I doing wrong?
Distinct does not work for your requirement. MAX, Min functions are not allowed to use with bit type. You could use Group by and SUM like this
SELECT
[ORDER].[order_id]
,CASE WHEN SUM( CASE WHEN [ORDERLINE].[is_subscription] = 1 THEN 1 ELSE 0 END) > 0 THEN 1
ELSE 0
END AS hasSubArticles
,CASE WHEN SUM( CASE WHEN [ORDERLINE].[is_setup] = 1 THEN 1 ELSE 0 END) > 0
THEN 1
ELSE 0
END hasSetupArticles
FROM [ORDER]
LEFT JOIN [ORDERLINE]
ON [ORDER].[order_id] = [ORDERLINE].[f_order_id]
WHERE [G_ORDER].[status] = 1
GROUP BY [ORDER].[order_id]

Group by in table

My code is :
SELECT
Student_ID ,dbo.tblVahed.Vahed_ID,
COUNT(Student_ID) AS State_All,
CASE
WHEN tblStudentsDocument.Student_Sex = N'مرد'
THEN COUNT(Student_ID)
END AS Count_Man,
CASE
WHEN tblStudentsDocument.Student_Sex = N'زن'
THEN COUNT(Student_ID)
END AS Count_Woman
FROM
dbo.tblStudentsDocument
INNER JOIN
dbo.tblVahed ON dbo.tblStudentsDocument.Vahed_ID = dbo.tblVahed.Vahed_ID
GROUP BY
dbo.tblVahed.Vahed_ID, Student_ID, Student_Sex
but I should group by only dbo.tblVahed.Vahed_ID. Any help appreicated.
Anything that's not aggregated in the SELECT field list must be included in the group by. If you don't want to group by it, then you shouldn't include it in the select list unaggregated. Your query should work as follows.
SELECT dbo.tblVahed.Vahed_ID,
COUNT( Student_ID) AS State_All ,
SUM(CASE WHEN tblStudentsDocument.Student_Sex = N'مرد' THEN 1 ELSE 0 END) AS Count_Man ,
SUM(CASE WHEN tblStudentsDocument.Student_Sex = N'زن' THEN 1 ELSE 0 END) AS Count_Woman
FROM dbo.tblStudentsDocument
INNER JOIN dbo.tblVahed ON dbo.tblStudentsDocument.Vahed_ID = dbo.tblVahed.Vahed_ID
GROUP BY dbo.tblVahed.Vahed_ID
Note I've removed student id, and rewritten the case statement to perform the aggregation in a different way.

SQL Server CASE - WHEN - ELSE

I have 2 tables like this:
Table CT: Number, CtID, Date, CTIE
Table VT: Number, VtID, Quantities
And my code:
SELECT
MAX(CT.Date), MAX(CT.CtID), VT.VtID,
SUM(VT.Quantities) AS SumVT,
CASE
WHEN CT.CTIE = 0 THEN SUM(VT.Quantities)
ELSE 0
END AS IMPORT,
CASE
WHEN CT.CTIE = 1 THEN SUM(VT.Quantities)
ELSE 0
END AS EXPORT
FROM
CT
INNER JOIN
VT ON CT.Number = VT.Number
GROUP BY
VT.VtID, CT.CTIE
ORDER BY
VT.VtID
This code works fine but the result is not what I want. With some VtID that have both CTIE = 1 and CTIE = 1, SQL now returns 2 separate rows with same VtID, one for CTIE = 0 and one for CTIE = 1. But I need it to display only 1 row for each VtID instead of 2.
Remove CT.CTIE in the group by and place your case statements inside the aggregate function
SElECT
MAX(CT.Date), MAX(CT.CtID), VT.VtID, SUM(VT.Quantities) AS SumVT,
SUM(CASE WHEN CT.CTIE = 0 THEN VT.Quantities ELSE 0 END) AS IMPORT,
SUM(CASE WHEN CT.CTIE = 1 THEN VT.Quantities ELSE 0 END) AS EXPORT
FROM CT INNER JOIN VT ON CT.Number=VT.Number
GROUP BY VT.VtID
ORDER by VT.VtID

Using OVER() if customer has watch gladiator then 1 else 0 SQL SERVER

I think I need some guidance as to what is wrong in my query. I am trying to do
Watched_Gladiator=CASE WHEN FilmName IN (CASE WHEN FilmName LIKE '%Gladiator%' THEN 1 END) then OVER(PARTITION BY Cust_Nr) THEN 1 ELSE 0 END
Tried this one too:
Watched_Gladiator=CASE WHEN FilmName IN (CASE WHEN FilmName LIKE '%Gladiator%' THEN Filmnamne END) then OVER(PARTITION BY Cust_Nr) THEN 1 ELSE 0 END
The Error I am currently getting is this:
Incorrect syntax near the keyword 'OVER'.
This is basically how my data looks like
Cust_Nr Date FilmName Watched Gladiator
157649306 20150430 Gladiator 1
158470722 20150504 Nick Cave: 20,000 Days On Earth 0
158467945 20150504 Out Of The Furnace 0
158470531 20150504 FilmA 0
157649306 20150510 Gladiator 1
158470722 20150515 Gladiator 1
I want to create a column (1 or zero) that shows if the customer has watched Gladiator then 1 ELSE 0. How can I do that?
I created a test column trying with a simple LIKE '%Gladiator%' THEN 1 ELSE 0. The problem with this solution is that it will show 1(one) more than once if the customer has watched multiple times. I only need 1 or zero.
I feel I am really close to finding a solution. I am very new to using OVER() and CASE WHEN but enjoying the thrill:=)
So you're saying that:
SELECT Cust_Nr, Date, FilmName,
CASE WHEN FilmName LIKE '%Gladiator%' THEN 1 ELSE 0 END as WatchedGladiator
FROM YourTable
WHERE YourColumn = #somevalue
Doesn't work? Because according to the data you've given, it should.
EDIT:
Well based on Tim's comment, I would simply add this bit to the query.
SELECT Cust_Nr, Date, FilmName, WatchedGladiator
FROM
(
SELECT Cust_Nr, Date, FilmName,
CASE WHEN FilmName LIKE '%Gladiator%' THEN 1 ELSE 0 END as WatchedGladiator
FROM YourTable
WHERE YourColumn = #somevalue
) as wg
WHERE WatchedGladiator = 1
The following does what you want for all films:
select r.*,
(case when row_number() over (partition by filmname order by date) = 1
then 1 else 0
end) as IsWatchedFirstAndGladiator
from results r;
For just Gladiator:
select r.*,
(case when filmname = 'Gladiator' and row_number() over (partition by filmname order by date) = 1
then 1 else 0
end) as IsWatchedFirst
from results r;
So you want to group by customer and add a column if this customer watched a specific film?
You could do:
SELECT Cust_Nr, MAX(Watched_Gladiator)
FROM( SELECT Cust_Nr,
Watched_Gladiator = CASE WHEN EXISTS
(
SELECT 1 FROM CustomerFilm c2
WHERE c2.Cust_Nr = c1.Cust_Nr
AND c2.FilmName LIKE '%Gladiator%'
) THEN 1 ELSE 0 END
FROM CustomerFilm c1 ) X
GROUP BY Cust_Nr
Demo
But it would be easier if you used the customer-table instead of this table, then you don't need the group-by.
Try grouping up to the cust/film level:
select
cust_nbr,
case when film_name like '%Gladiator%' then 1 else 0 end
from
(
select
cust_nbr,
film_name
from
<your table>
group by
cust_nbr,
film_name
) t
Or, as an alternative:
select distinct cust_nbr
from
<your table>
where
filmname = 'Gladiator'

SQL Percentage calculation

Is it possible in SQL to calculate the percentage of the 'StaffEntered' column's "Yes" values (case when calculated column) out of the grand total number of orders by that user (RequestedBy)? I'm basically doing this function now myself in Excel with a Pivot table, but thought it may be easier to build it into the query. Here is the existing sample SQL code:
Select
Distinct
RequestedBy = HStaff.Name,
AccountID = isnull(pv.AccountID, ''),
StaffEntered = Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end
FROM
[dbo].[HOrd] HOrd WITH ( NOLOCK )
left outer join HStaff HStaff with (nolock)
on HOrd.Requestedby_oid = HStaff.ObjectID
and HStaff.Active = 1
left outer join DictionaryItem DictionaryItem2 WITH (NOLOCK)
ON HSUser1.PreferenceGroup_oid = DictionaryItem2.ObjectID
AND DictionaryItem2.ItemType_oid = 98
Here is what I am doing in Excel currently with the query results, I have a pivot table and I am dividing the "Yes" values of the "StaffEntered" field out of the Grand Total number of entries for that specific "RequestedBy" user. Essentially Excel is doing the summarization and then I am doing a simple division calculation to obtain the percentage.
Thanks in advance!
You didn't provide a lot in the way of details but I think this should be pretty close to what you are looking for.
select HStaff.Name as RequestedBy
, isnull(pv.AccountID, '') as AccountID
, Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end as StaffEntered
, sum(Case When DictionaryItem2.Name like '%PLB%' Then 1 Else 0 end) / GrandTotal
From SomeTable
group by HStaff.Name
, isnull(pv.AccountID, '')
, GrandTotal
Giving the FROM part of your SQL Statement would allow us to create a more correct answer. This statement will get the totals of yes/no per HStaff name and add it to each detail record in your SQL statement:
WITH cte
AS ( SELECT HStaff.Name ,
SUM(CASE WHEN dictionaryItem2.Name LIKE '%PLB%' THEN 1
ELSE 0
END) AS YesCount ,
SUM(CASE WHEN dictionaryItem2.Name NOT LIKE '%PLB%'
THEN 1
ELSE 0
END) AS NotCount
FROM YourTable
GROUP BY HStaff.Name
)
SELECT HStaff.Name AS requestedBy ,
ISNULL(pv.AccountID, '') AS AccountID ,
CASE WHEN DictionaryItem2.Name LIKE '%PLB%' THEN 'Yes'
ELSE 'No'
END AS StaffEntered ,
cte.YesCount / ( cte.YesCount + cte.NotCount ) AS PLB_Percentage
FROM yourtable
INNER JOIN cte ON yourtable.Hstaff.Name = cte.NAME

Resources