Create conditional for COUNT - sql-server

Forgive me if this has been asked but I have been unable to find a solution for this. I'm using the COUNT function, and would like for all returned values greater than 5 to return as ">5".
It seems that the HAVING clause is the way to go, but I don't know how to make it conditional.
Thanks in advance.
SELECT DISTINCT
Column A
COUNT(*) AS VISITS
FROM TABLE A
GROUP BY
Column A
ORDER BY
Column A

you can use case statement to return the correct label,
SELECT ColumnaA, case when count(*) > 5 then '>5' else cast(count(*) as varchar(4)) end as visits
from tableA
group by ColumnA
order by ColumnA

Related

SELECT INTO query

I have to write an SELECT INTO T-SQL script for a table which has columns acc_number, history_number and note.
How do i facilitate an incremental value of history_number for each record being inserted via SELECT INTO.
Note, that the value for history_number comes off as a different value for each account from a different table.
SELECT history_number = IDENTITY(INT,1,1),
... etc...
INTO NewTable
FROM ExistingTable
WHERE ...
You could use ROW_NUMBER instead of identity i.e. ROW_NUMBER() OVER (ORDER BY )
SELECT acc_number
,o.historynumber
,note
,o.historynumber+DENSE_RANK() OVER (Partition By acc_number ORDER BY Note) AS NewHistoryNumber
--Or some other order by probably a timestamp...
FROM Table t
INNER JOIN OtherTable o
ON ....
Working Fiddle
The will give you an incremented count starting from history number for each accnum. I suggest you use a better order by in the rank but there was not enough info in the question.
This answer to this question may help you as well
Question
Suppose your SELECT statement is like this
SELECT acc_number,
history_number,
note
FROM [Table]
Try this Query as below.
SELECT ROW_NUMBER() OVER (ORDER BY acc_number) ID,
acc_number,
history_number,
note
INTO [NewTable]
FROM [Table]

Checking SQL MAX() Function returning null

My problem is if my table is empty or the column on which I am using max function does not have the value I have specified, then why is sqlDataReader.hasRows TRUE?
It is giving a null record...how do I solve this problem??
Thanks in advance.
An aggregate function like MAX() will always return one row per group. In your case, your group is the whole table. Therefore you get a one row resultset with the MAX value. Since you don't have data in your table, the MAX value is undefined, therefore NULL.
For better understanding try to replace MAX with COUNT. This will also return one row but with value 0. I think this is more intuitive and will help you better to understand what is happening.
Make your query into a derived table and filter out null values in the main query.
select T.MaxValue
from (
-- Your query goes here
select max(Value) as MaxValue
from YourTable
where SomeCol > 10
) as T
where T.MaxValue is not null
Or, use the HAVING clause because HAVING can be used with aggregate functions:
select max(Value) from YourTable where SomeCol > 10
HAVING max(Value) is not null
you can use:
select top(select COUNT(*) from tbl) max(field) from tbl

How ROW_NUMBER used with insertions?

I've multipe uniond statements in MSSQL Server that is very hard to find a unique column among the result.
I need to have a unique value per each row, so I've used ROW_NUMBER() function.
This result set is being copied to other place (actually a SOLR index).
In the next time I will run the same query, I need to pick only the newly added rows.
So, I need to confirm that, the newly added rows will be numbered afterward the last row_number value of the last time.
In other words, Is the ROW_NUMBER functions orders the results with the insertion order - suppose I don't adding any ORDER BY clause?
If no, (as I think), Is there any alternatives?
Thanks.
Without seeing the sql I can only give the general answer that MS Sql does not guarantee the order of select statements without an order clause so that would mean that the row_number may not be the insertion order.
I guess you can do something like this..
;WITH
cte
AS
(
SELECT * , rn = ROW_NUMBER() OVER (ORDER BY SomeColumn)
FROM
(
/* Your Union Queries here*/
)q
)
INSERT INTO Destination_Table
SELECT * FROM
CTE LEFT JOIN Destination_Table
ON CTE.Refrencing_Column = Destination_Table.Refrencing_Column
WHERE Destination_Table.Refrencing_Column IS NULL
I would suggest you consider 'timestamping' the row with the time it was inserted. Or adding an identity column to the table.
But what it sounds like you want to do is get current max id and then add the row_number to it.
Select col1, col2, mid + row_number() over(order by smt) id
From (
Select col1, col2, (select max(id) from tbl) mid
From query
) t

Calculating mean from column values

I want a result-set as below from a table:
I tried query:
select sdate, sum(PG)/sum(PT)*100 AS Score, avg(score) as Mean from table
but I am not getting the correct Mean.
Mean is: sum of all scores / total number of scores.
I want to show mean as computed column. In the above result-set, total of scores is 309 and when divided by 4 (total number of rows) it gives 77.25.
I want to display the result as shown in the result-set.
I believe you're looking for something like:
SELECT sdate,
SUM(PG)/SUM(PT)*100 AS Score,
(SELECT AVG(score) FROM table) AS Mean
FROM table
This should set the mean to the average score across the entire table. If you have WHERE clauses for filtering, you would have to place them in both the subquery and the main query.
EDIT
If the original SQL statement has a GROUP BY, as it sounds like it does, then you could use the following query to achieve what you're looking for:
SELECT sdate,
SUM(PG)/SUM(PT)*100 AS score,
(SELECT AVG(score)
FROM (SELECT CAST(SUM(PG)/SUM(PT)*100 AS FLOAT) AS score
FROM table
GROUP BY sdate) scores) AS Mean
FROM table
GROUP BY sdate
It's not pretty, but I believe it'll accomplish what you're looking for.
DECLARE #mean DECIMAL(5,2);
SELECT #mean = AVG(score) FROM dbo.table;
SELECT sdate, score, Mean = #mean FROM dbo.table;
I think this will work for you
as you need to show avg in each row , i am using subquery to generated that avg each time .
create table mean
(
d date,
score int
)
insert into mean values ('01/01/2013',50),('02/01/2013',60)
,('03/01/2013',40),('04/01/2013',30)
,('05/01/2013',20),('06/01/2013',20)
SELECT d,score,(select sum(score)/count(*) from mean) from mean
SQL FIDDLE LINK
but it will be good if you count avg first and use that variable in your select statement
SELECT d,score,
ISNULL((select CONVERT(DECIMAL(10,2),CONVERT(DECIMAL(10,2),sum(score))/count(*) ) from #mean) ,0) as mean from #mean

How do I make this SQL query work (computed column with nested query)?

I want to have a computed column that is true if the field asofdate is equal to the maximum asofdate in the table, otherwise false. I tried the following but I am getting a syntax error. What is the right way to do this?
select
case asofdate
when select max(asofdate) from sometable then 1
else 0
end
from sometable
Alternatively, is it possible to have a computed column along the lines of
case asofdate
when END OF PREVIOUS MONTH then 1
else 0
end
From the MSDN article
A computed column is computed from an
expression that can use other columns
in the same table. The expression can
be a noncomputed column name,
constant, function, and any
combination of these connected by one
or more operators. The expression cannot be a subquery.
So no you can't make a computed column that way.
You cannot do it in an computed column, since the computed column can be only computed from the values of other columns in the same record.
You can do it in a view, instead:
CREATE VIEW
v_with_last
AS
SELECT *, CASE asofdate WHEN MAX(asofdate) OVER () THEN 1 ELSE 0 END AS the_last
FROM sometable
Unfortunately, you cannot index this view.
In MS Sql Server
SELECT case asofdate
WHEN (SELECT MAX(asofdate) FROM sometable) THEN 1
ELSE 0 END
FROM sometable
EDIT based on comments
To get the end of the previous month -
SELECT DATEADD(dd,-(DAY(asofdate)),asofdate)
I dont know if this would work, but you could create a computed column with formula as 'MAX(asofdate)', create an index on that column and then create a view that just compares the computed column with asofdate. Maybe not the best possible solution, but might be slightly better than just doing a subquery.
so the maximum value of asofdate is stored in a table called sometable right? In that case you dont have to check it using a subquery for every record. You can stored it in a variable and then check the current asofdate towards that.
declare #maxAsOfDate datetime;
Select #maxAsOfDate = max(asofdate) from sometable;
Select case when asofdate >= #maxAsOfDate then 1 else 0 end from sometable
Cheers!

Resources