Select value from column and make it act like a field - sql-server

i'm doing a chart, i need to select
SELECT Bid
, ID
, date
, CASE
WHEN status IS NULL THEN 'unsuccessful'
WHEN status = 'Won' THEN 'successful'
WHERE status = 'Won'
OR status IS NULL
But i want that the value from the status example unsucessful is display as field

Changes according to requirements in comments.
As I understand, you need your query to give you four columns: Year, Month, NumberOfWins, NumberOfFails.
Thus grouping by Year and Month is necessary. For each Year and Month combination you need to know number of rows that have status IS NULL condition true, and number of rows, that have status = 'Won' condition true.
Please verify if this query suits your needs:
SELECT
YEAR(date) as Year,
MONTH(date) as Month,
SUM(case when status IS NULL then 1 else 0 end) as NumberOfFails,
SUM(case when status = 'Won' then 1 else 0 end) as NumberOfWins
FROM
<your-table-name-here>
WHERE status = 'Won'
OR status IS NULL
GROUP BY
YEAR(date), MONTH(date)
ORDER BY
Year, Month
Notice, that WHERE condition is only necessary if you have plenty of rows that do not match neither condition (I am not sure whether SQL Server would be able to optimize it).
I've also added ORDER BY clause as you probably would like to order data in your chart.
I've also assumed, that by writing 'month' you actually meant year and month. If that is not true simply remove year related statements from the query.

Related

Group by to Avoid with Aggregate function

I have query where I am using Case when statement to get no of customer covered on particular date
, but in that I have some filter to apply , I want only those customer covered where Invoice Number is not zero .
But When I am putting Invoice no in case then asking me to do group by and group by is giving me result invoice by invoice, I need a single query result, If I don't write InvoiceNo!='0' then I am getting single line result but I want to put this Filter, I tried while putting Sum also before case but gives me an error that Cannot perform an aggregate function on an expression containing an aggregate or a subquery
this is my query
select sum(Amt) as Amnt, LineManager, Staffname , month(date) as month , FORMAT(date, 'dddd') AS [Day Name]
,**(CASE WHEN (Order_type ='SALES_ORDER' and InvoiceNo!='0' ) THEN COUNT(DISTINCT(customer)) else 0 END) as [Customercovered]**
from SalesTrasncation Salest
INNER JOIN Customer cus ON Salest.SITE=cus.customercode
WHERE date between '2022-11-24' and '2022-11-24'
group by LineManager,Staffname , month(date) ,date,order_type ;

SQL Server condition case doesnt work as intended

I want my SQL to display the overdue count when the condition is the status name showed closed on the exact due date then the count will be set as 1. For example, on the due date, the status name only became closed.
select
category, COUNT(overdue) as overdue2
from
(select
Category, due,
case when DATEDIFF(day, Due, SYSDATETIME()) = 0 then 1
else 0
end as overdue
from
FeedbackDetail
where
StatusName = 'Closed' and
FeedbackDatetime >= '2018-01-01') a
Group by
Category
My expected result is to display the count where the statusname is closed on the exact due date time.
Any idea on this?
The COUNT aggregate function counts existant (non-null) values, so it will count 0 as well as 1. Since you did not post the whole query and we have no idea what a1 is, the only solution that can be proposed is:
Use SUM instead of COUNT.
You can modify the query like given below for better performance and working.
DECLARE #currentDateTime DATETIME = GETDATE()
select
category, SUM(overdue) as overdue2
from
(select
Category,
case when DATEDIFF(day, Due, #currentDateTime) = 0 then 1
else 0
end as overdue
from
FeedbackDetail
where
StatusName = 'Closed' and
FeedbackDatetime >= '2018-01-01') a
Group by
Category

Query returns no results

I am running a query that counts emails sent by customers, based on their subject.
DECLARE #LastMonthNo varchar(2)
DECLARE #LastMYear varchar(4)
SET #LastMonthNo = DATEPART(m,DATEADD(m,-1,GetDate()))
SET #LastMYear = DATEPART(yyyy,DATEADD(m,-1,GetDate()));
SELECT
CustID, CustName, CustEmail,
ISNULL(SUM(CASE WHEN EmailSubject LIKE 'KeyWord' THEN 1 END),0) AS TotalEmail
FROM
TableEmails
WHERE
DATEPART(M, DATESENT) = #LastMonthNo
AND DATEPART(YYYY, DATESENT) = #LastYearNo
GROUP BY CustID, CustName, CustEmail
For some customers, the query returns no results. I do not mean NULL, I mean there is no record at all. However, I need to identify those customers.
What can I do to get the query to generate some sort of results? A 0 would be perfect.
Try something like this..
SELECT CustID, CustName, CustEmail,
SUM(CASE WHEN EmailSubject LIKE 'KeyWord'
AND DATEPART(YYYY,DATESENT)=#LastYearNo
AND DATEPART(YYYY,DATESENT)=#LastYearNo
THEN 1 ELSE 0 END) AS TotalEmail,
FROM TableEmails
GROUP BY CustID, CustName, CustEmail
What is the difference?
WHERE part executes before GROUP BY. So, with your query, you are grouping your results after other customers are filtered out. If you move that condition to CASE statement, you will check that condition on each record in the table regardless of dates. Hope that makes sense.

Incorrect Syntax in sql server , can't figure out the reason

I'm trying to uodate a column in table , depending on combination of two columns.If the value was null , since beginning of time I set it to 0 otherwise I set it to max value until that date.I'm using SQL SERVER 2008.Thanks for the help in advance!
update Table1
set value = a.value
from
( SELECT product,
week ,
case when value is null then
(case when max(value) over(PARTITION BY product ORDER BY week ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) is null then 0
else (max(value) over (PARTITION BY product ORDER BY week ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) end )
else value end as value
from table2 ) a
where a.product = table1.product
and a.week = table1.week
The ROWS keyword was added to the OVER clause in 2012. You won't be able to use it for 2008.
https://msdn.microsoft.com/en-us/library/ms189461(v=sql.110).aspx

Printing the current value and previous value between the date range

I have a sample data like this
ID DATE TIME STATUS
---------------------------------------------
A 01-01-2000 0900 ACTIVE
A 05-02-2000 1000 INACTIVE
A 01-07-2000 1300 ACTIVE
B 01-05-2005 1000 ACTIVE
B 01-08-2007 1050 ACTIVE
C 01-01-2010 0900 ACTIVE
C 01-07-2010 1900 INACTIVE
From the above data set, if we only focus on ID='A' we note that A was initally active, then became inactive on 05-02-2000 and then it was inactive until 01-07-2000.
Which means that A was inactive from 05-Feb-2000 to 01-July-2000.
My questions are:
if I execute a query with (ID=A, Date=01-04-2000) it should give me
A 05-02-2000 1000 INACTIVE
because since that date is not available in that data set, it should search for the previous one and print that
Also, if my condition is (ID=A, Date=01-07-2000) it should not only print the value which is present in the table, but also print a previous value
A 05-02-2000 1000 INACTIVE
A 01-07-2000 1300 ACTIVE
I would really appreciate if any one can assist me solve this query. I am trying my best to solve this.
Thank you every one.
Any take on this?
Afaq
Something like the following should work:
SELECT ID, Date, Time, Status
from (select ID, Date, Time, Status, row_number() over (order by Date) Ranking
from MyTable
where ID = #SearchId
and Date <= #SearchDate) xx
where Ranking < 3
order by Date, Time
This will return at most two rows. Its not clear if you are using Date and Time datatyped columns, or if you are actually using reserved words as column names, so you'll have to fuss with that. (I left out Time, but you could easily add that to the various orderings and filterings.)
Given the revised criteria, it gets a bit trickier, as the inclusion or exclusion of a row depends upon the value returned in a different row. Here, the “second” row, if there are two or more rows, is included only if the “first” row equals a particular value. The standard way to do this is to query the data to get the max value, then query it again while referencing the result of the first set.
However, you can do a lot of screwy things with row_number. Work on this:
SELECT ID, Date, Time, Status
from (select
ID, Date, Time, Status
,row_number() over (partition by case when Date = #SearchDate then 0 else 1 end
order by case when Date = #SearchDate then 0 else 1 end
,Date) Ranking
from MyTable
where ID = #SearchId
and Date <= #SearchDate) xx
where Ranking = 1
order by Date, Time
You'll have to resolve the date/time issue, since this only works against dates.
Basically you need to pull a row if, for the specified date, it is:
1) the last record, or
2) the last inactive record.
And the two conditions may match the same row as well as two distinct rows.
Here's how this logic could be implemented in SQL Server 2005+:
WITH ranked AS (
SELECT
ID,
Date,
Time,
Status,
RankOverall = ROW_NUMBER() OVER ( ORDER BY Date DESC),
RankByStatus = ROW_NUMBER() OVER (PARTITION BY Status ORDER BY Date DESC)
FROM Activity
WHERE ID = #ID
AND Date <= #Date
)
SELECT
ID,
Date,
Time,
Status,
FROM ranked
WHERE RankOverall = 1
OR Status = 'INACTIVE' AND RankByStatus = 1

Resources