SQL Case Expression with a Where Clause - sql

I have the following example Data set that was created by the following query that sets an employee as "Active' or 'Inactive" based on if they worked any hours during a month.
Select Concat([First Name],' ', [Last Name]) AS 'FullName',
CASE (SUM([Week 1] + [Week 2] + [Week 3] + [Week 4]))
When 0 Then 'Inactive'
ELSE 'Active'
END [Status]
From dbo.hours
Group by [first name], [last name]
FullName
Status
Alan Brewer
Active
Alejandro McGuel
Inactive
Alex Nayberg
Active
Im trying to get rid of all the 'Active' Status rows so that my query only displays those who are 'inactive'. I attempted to add WHERE Status = Inactive between the FROM and GROUP BY expression but it returns no results. (Does not give an error, just returns empty columns).
Anyone know what I am missing?

You can't add a WHERE condition on the Status column just like that since it's not available to WHERE clause .. you can use that query as inline view and do the condition check in outer query like
select * from (
Select Concat([First Name],' ', [Last Name]) AS 'FullName',
CASE (SUM([Week 1] + [Week 2] + [Week 3] + [Week 4]))
When 0 Then 'Inactive'
ELSE 'Active'
END [Status]
From dbo.hours
Group by [first name], [last name] ) xxx
where Status != 'Active';

You need a HAVING clause, but also for your requirement you don't need the CASE expression:
SELECT CONCAT([First Name],' ', [Last Name]) AS FullName,
'Inactive' [Status]
FROM dbo.hours
GROUP BY [first name], [last name]
HAVING SUM([Week 1] + [Week 2] + [Week 3] + [Week 4]) = 0

CTE will work as well:
with cte as(
Select Concat([First Name],' ', [Last Name]) AS 'FullName',
CASE (SUM([Week 1] + [Week 2] + [Week 3] + [Week 4]))
When 0 Then 'Inactive'
ELSE 'Active'
END [Status]
From dbo.hours
Group by [first name], [last name])
select FullName from cte where Status <> 'Active'

Related

Insert into table when the day is Monday

Is there a way in which I can insert data from one table into another when today is Monday?
I tried making something like the below, using CASE WHEN, however it doesn't quite work right, any help would be welcomed
INSERT INTO [dbo].[WF_All]
SELECT (CASE WHEN (DATENAME(WEEKDAY,FLOOR(convert(float,getdate()))))='MONDAY' THEN
(
SELECT [Parent Number]
,[Parent Name]
,[Customer Number]
,[Customer Name]
,[Collector]
,[Outstanding]
FROM dbo.[Invoices]
)
ELSE NULL END )
yes , like this :
INSERT INTO [dbo].[WF_All]
SELECT [Parent Number]
,[Parent Name]
,[Customer Number]
,[Customer Name]
,[Collector]
,[Outstanding]
FROM dbo.[Invoices]
WHERE DATENAME(WEEKDAY,GETDATE()) = 'Monday'
or
... WHERE DATEPART(WEEKDAY, GETDATE()) = 2 --Monday
Is this what you want.
if datename(weekday,getdate()) = 'MONDAY' then
INSERT INTO [dbo].[WF_All] (
-- column names go here
)
SELECT [Parent Number]
,[Parent Name]
,[Customer Number]
,[Customer Name]
,[Collector]
,[Outstanding]
FROM dbo.[Invoices]

Create a value adding two columns together

I am attempting to define and new column called End Year that is the calculation of another column plus a number representing number of years. For some reason my script does not recognize the new column called Allocation Year using the excerpt below SQL statement in SQL Server 2008. Note that Contract Year is an existing column that is identified in the non-redacted full script:
,[Allocation Type] =
CASE
WHEN left([contract type] ,1)'1' = THEN 'O&M'
ELSE 'N/A'
END
,[Allocation Year] =
CASE
WHEN [Contract Year]='XXXX' THEN '0'
ELSE CAST ([Contract Year] AS INT)
END
,[End Year] =
CASE
WHEN [Allocation Type]='O&M' THEN [Allocation Year] + 6
END
Columns are named with the AS keyword (which can also be elided in many cases), not with the = operator.
SQL Server does not let you reference other columns or aliases in a SELECT clause - you have to use a subquery:
Like so:
SELECT
*,
CASE WHEN [Allocation Type] = 'O&M'
THEN [Allocation Year Temp] + 6
ELSE NULL
END AS [Allocation Year]
FROM
(
SELECT
CASE WHEN LEFT( [Contract type], 1 ) = '1'
THEN 'O&M'
ELSE 'N/A'
END AS [Allocation Type],
CASE WHEN [Contract Year] = 'XXXX'
THEN '0'
ELSE CAST( [Contract Year] AS int )
END AS [Allocation Year Temp],
*
FROM
....
)
If you want to put everything in one select query, then try this one. Hope this helps. Thanks.
,[End Year] =
CASE
WHEN left([contract type] ,1)='1' THEN
(CASE
WHEN [Contract Year]='XXXX' THEN 6
ELSE (CAST ([Contract Year] AS INT) + 6 )
END)
END
You cannot reference computed columns in the SELECT statement. You'll have to repeat the calculation (or use subqueries like Dai suggested):
,[Allocation Type] =
CASE
WHEN left([contract type] ,1)='1' THEN 'O&M'
ELSE 'N/A'
END
,[Allocation Year] =
CASE
WHEN [Contract Year]='XXXX' THEN 0
ELSE CAST ([Contract Year] AS INT)
END
,[End Year] =
CASE
WHEN left([contract type] ,1)='1' THEN (CASE
WHEN [Contract Year]='XXXX' THEN 0
ELSE CAST ([Contract Year] AS INT)
END) + 6
END

Dynamic SQL column names

I have a query like:
SELECT [Week 1].Product, [Week 2].Product, [Week 3].Product, [Week 4].Product, Sum([Week 1].Transaction_Amount), Sum([Week 2].Transaction_Amount), Sum([Week 3].Transaction_Amount), Sum([Week 4].Transaction_Amount)
FROM [Week 2],[Week 3],[Week 3],[Week 4];
I have data for 70 weeks name [week 1] to [week 70]
Is it possible to make [week 1],[Week 2],[Week 3],[Week 4] dynamic.
(i,e) have a master table where I can have 4 week names like [Week 8], [Week 6], [Week 45], [Week 18] and replace the [Week 1], [Week 2], [Week 3], [Week 4] with the above 4 in my query
IT IS AN MS ACCESS APPLICATION. Sorry I did not mention previously.
Yes you can do that using a dynamic query and then using EXEC or sp_executesql to execute the query
The following will be a pseudo code which you can improvise as per your requirement.
DECLARE #STartCount, #TableCount, #Query, #SubQuery, #WeekTblName
SET #StartCount = 1
SELECT #TableCount = Count(*) FROM Master_Table
WHILE(#StartCount <= #TableCount)
BEGIN
SELECT #WeekTblName = Col_Name FROM Master_Table WHERE ID = #StartCount
SET #SubQuery = #SubQuery + #WeekTblName + ' AS [Week ' + #STartCount + '], '
SET #StartCount = #StartCount + 1
END
SET #SUBQUERY = LEFT(#SUBQUERY, LEN(#SUBQUERY) - 2);
SET #Query = 'SELECT [Week 1].Product, [Week 2].Product, [Week 3].Product, [Week 4].Product, Sum([Week 1].Transaction_Amount), Sum([Week 2].Transaction_Amount), Sum([Week 3].Transaction_Amount), Sum([Week 4].Transaction_Amount)
FROM ' + #SubQuery
EXEC(#Query)
Hope this helps
UPDATE
Create some VBA code on a button which dynamically creates the select query. How to build a dynamic query
You could:
1) Change your table structure so that you have a single Table for all weeks e.g. Week (ID, WeekNumber, column1, column2...). And then in your Select statement you can add a where clause to use a parameter to select which weeks you are interested in. This is dependant on all the weeks tables having the same structure.
2) Use Dynamic SQL to build your select statement and replace your table names. See sp_executesql

SQL Pivot Table Subtotal Syntax error

Hoping someone can help me. I was able to put together this SQL script but it coming back with minor errors here and there. I'be been trying to debug for over a week now. Please help. the first error message is "Incorrect syntax near ')'." If you fixe that it keeps on throwing more out so I'm thinking I'm not coding this correctly. I am unable to save changes that do work. it tell me the save request was aborted. Working with SQL Server 2008 r2
SELECT
PublicationID AS PubID, (PubNum + '- ' + PubTitle) AS [Pub Descr],
CONVERT(Varchar(10), [Datestamp], 101) AS [Date Printed],
QtyPrinted AS [Qty Printed],
[2] AS [Tyler Inventory],
[1] AS [Central Inventory],
[3] AS [Mailing House Inventory],
(
SELECT SUM(S)
FROM
(
SELECT [1] UNION ALL
SELECT [2] UNION ALL
SELECT [3]
) AS T (S)) AS [Current Inventory],
RecycledQty AS [Recycled],
MailingVendorName AS [Mailing Vendor],
PrintVendorName AS [Print Vendor]
FROM
(
SELECT
PublicationID, LocationID, Balance, PubNum,
PubTitle, ItemPerCase, Datestamp, Deleted,
RecycledQty, MailingVendorName, PrintVendorName,
QtyPrinted
FROM
(
dbo.view_PubInventory_Main_Summary_RAW) x PIVOT (sum(balance) FOR
LocationID IN ([1], [2], [3])) p)
SELECT *
FROM
(SELECT PUBID, [Pub Descr], [Date Printed], [Qty Printed],
[Tyler Inventory], [Central Inventory],
[Mailing House Inventory], [Current Inventory], [Recycled],
[Mailing Vendor]
FROM GG
) AS T
Hard to follow exactly what you're after, but I think you want Current Inventory to just be [1]+[2]+[3], and you didn't alias your subquery. The query at the bottom looks fine.
SELECT PublicationID AS PubID
, PubNum + '- ' + PubTitle AS [Pub Descr]
, CONVERT(VARCHAR(10), [Datestamp], 101) AS [Date Printed]
, QtyPrinted AS [Qty Printed]
, [2] AS [Tyler Inventory]
, [1] AS [Central Inventory]
, [3] AS [Mailing House Inventory]
, [1]+[2]+[3] AS [Current Inventory]
, RecycledQty AS [Recycled]
, MailingVendorName AS [Mailing Vendor]
, PrintVendorName AS [Print Vendor]
FROM ( SELECT PublicationID
, LocationID
, Balance
, PubNum
, PubTitle
, ItemPerCase
, Datestamp
, Deleted
, RecycledQty
, MailingVendorName
, PrintVendorName
, QtyPrinted
FROM dbo.view_PubInventory_Main_Summary_RAW
PIVOT ( SUM(balance) FOR LocationID IN ( [1], [2], [3] ) ) p
)AS Sub

T-SQL SUM Total

Below I have a T-SQL query that brings back amount of purchased items, less discounts and the total - grouped by month/year of purchase. How can I update the Query to return a Grand Total Row
where I would can add up the amounts in the Total Column?
It would be good to be able to add up all the rows but my
main item is I need to be able to get a grand total. Thanks.
Select DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4))
AS [Month],
SUM(Amount) AS [Amount],
SUM(Discount1) AS [Discount 1],
SUM(Discount2) AS [Discount 2],
SUM(Amount - Discount1 - Discount2) AS [Total]
From
Orders
JOIN Customer on orders.cust_ky=customer.cust_ky
GROUP BY DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4))
ORDER BY MAX(OrderDate)
Depending on your version of sql-server, you might be able to implement the rollup function (SQL-Server 2005+):
Select DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4)) AS [Month],
SUM(Amount) AS [Amount],
SUM(Discount1) AS [Discount 1],
SUM(Discount2) AS [Discount 2],
SUM(Amount - Discount1 - Discount2) AS [Total]
From Orders
JOIN Customer
on orders.cust_ky=customer.cust_ky
GROUP BY ROLLUP(DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4)))
ORDER BY MAX(OrderDate)
Or you can use a UNION ALL similar to this, where the second query gets the total without the GROUP BY:
Select DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4)) AS [Month],
SUM(Amount) AS [Amount],
SUM(Discount1) AS [Discount 1],
SUM(Discount2) AS [Discount 2],
SUM(Amount - Discount1 - Discount2) AS [Total]
From Orders
JOIN Customer
on orders.cust_ky=customer.cust_ky
GROUP BY DATENAME(month, [OrderDate]) + ' ' + CAST(YEAR(OrderDate) AS CHAR(4))
union all
Select 'Total',
SUM(Amount) AS [Amount],
SUM(Discount1) AS [Discount 1],
SUM(Discount2) AS [Discount 2],
SUM(Amount - Discount1 - Discount2) AS [Total]
From Orders
JOIN Customer
on orders.cust_ky=customer.cust_ky