SQL Server Query - How to append row showing total record count? - sql

What is the best approach to append a row to a SQL Server query showing the total count of rows resulting from the query? UNION is one way, but seems very inefficient:
SELECT col1, col2 FROM tbl1
UNION ALL
SELECT STR(COUNT(col1)), NULL FROM tbl1
ROLLUP isn't an option because it requires GROUP BY, which we're not using for the queries in question.

You can use GROUPING SETS for this
SELECT
CASE WHEN GROUPING(col1) = 0 THEN col1 ELSE CAST(COUNT(*) AS varchar(30)) END AS col1,
col2
FROM tbl1
GROUP BY GROUPING SETS (
(col1, col2),
()
);
The GROUPING function will tell you whether the row is the Total row or not.
This does have the effect of grouping the columns which could be a different result and possibly less efficient. But if you include a unique/primary key as the first column in the grouping list then this shouldn't make a difference, and should be almost as performant as the original query.
You can also use a window function, which will return the total on each row as another column
SELECT
col1,
col2,
COUNT(*) OVER ()
FROM tbl1;

Related

SQL filtering for table based on 3rd column's value

How should my SQL be so that the table mentioned above should have the expected output using SQL. The filtering happens using the col 3 value. Row with the highest col 3 value for a particular col 1 value is selected in the output.
You can use ROW_NUMBER() window function
SELECT col1, col2, col3 from (
SELECT row_number() over (partition by col1 order by col3 desc) sn, * from your_table_name
) a WHERE sn=1;
I assume you require the usage of the WHERE clause in SQL which acts as a method to filter results based on a conditional.
Considering you want all entries rather than any given entry one that matches, you can use the following (written in MySQL) which uses a nested SELECT statement:
SELECT *
FROM Table
WHERE col3=(SELECT MAX(col3) FROM Table);

Pick duplicate record within grouping records?

I had an history table in which duplicate records are entered due to history_date_time column.
Because of some process or loading issue i get this duplicate record.
I used a query like
SELECT (col1, col2), COUNT(*)
FROM table_name
GROUP BY (col1, col2)
HAVING COUNT(*) >1;
I grouped a records based on col1 and col2 but the problem is
i may have different column with different records. I want to pick unique records within the grouping records by checking all columns
How can i achieve this... using oracle sql query.. i need query
Sorry i dont have a proper table structure right now.
Should be
SELECT col1, col2, COUNT(*)
FROM table_name
GROUP BY col1, col2
HAVING COUNT(*) > 1;
Alternatively, if it must be a "group" of columns, perhaps you meant something like this?
SELECT col1 ||'-'|| col2 col, COUNT(*)
FROM table_name
GROUP BY col1 ||'-'|| col2
HAVING COUNT(*) >1;
Sample data would help.

How to use group-by and get other rows results

Question: if this is my data:
col1,col2,col3,col4
===================
www.com,0,dangerous,reason A
www.com,1,dangerous 2,reason B
I want the a single result where column 2 value is max, so I will use in my select the Max(col2) function - but how can I get those corresponding col3 and col4 row ?
select
col1, max(col2), col3, col4
group by
col1
and ???
Thanks
Idan
You can use order by and limit to one row. The ANSI-standard syntax is:
select t.*
from t
order by t.col2 desc
fetch first 1 row only;
Not all databases support the fetch first clause, so you might have to use select top 1, limit, or some other construct.
You can use where in select statement
Like
Select * from table name where col2=max(col2)
You can get max column entire row with single value
If the column col2 which contain same value like 1,1,2,2 at this time above query return the 2 rows. At that time if you want single row you want to use this
Select * from table name where col2=max(col2) fetch first 1 row only
Might be this helpful

Perform Union/OR Operation between where clause and having Clause

I am working on implementation for a SQL which should display results with Union operation between Where and Having Clause.
For example,
Select * from table where col1= 'get' group by col2 (OR/UNION) having avg(col3) >30 . This is not valid but trying to give use a case
The purpose of the sql statement is to return result set which satisfies both where and having conditions.
Lets say I have a table1, has with col1, col2, col3, col4 and large data in the table. Now, There is a use case in which user wants to see results when selects filters with specific crtieria col1 ='Y', avg(col2) >10, avg(col3*col4) =30 in filters list. Now, I have to create a criteria, such that, I should return all results which satisfies col1 ='Y' OR avg(col2) >10 OR avg(col3*col4) =30 , like we do in where clause with OR operator but here we have both where clause and having clause –
Like, the below query
resultset1 <= select * from table1 where col1= 'get';
resultset2 <= select * from table1 group by col2 having avg(col3) >30
final results = resultset1+ resultset2
Do any one have better approach or ideas in implementing such scenario?
Lets say I have filters combinations as below
col1 =23
OR
avg(col2) >30
AND
avg(col3) =10
OR
avg(col1) <10
AND
col2 =10
I need to display results satisfying these criteria in SQL
It's not clear what do you want from this quasi SQL. I guess you need to select records with two conditions col1= 'get' AND /OR ? having avg(col3) >30. So here is the solution:
Select * from table
where (col1= 'get')
OR
col2 in (SELECT col2 FROM table GROUP BY col2 HAVING avg(col3) >30)
If you need both conditions where true then replace OR with AND.
If you need to count AVG only for col1 = 'get' then add this condition into the subquery:
Select * from table
where (col1= 'get')
OR
col2 in (SELECT col2 FROM table WHERE (col1= 'get')
GROUP BY col2
HAVING avg(col3) >30)
SELECT <resultset1> --resultset based on a WHERE clause
UNION
SELECT <resultset2> --resultset based on HAVING
In general, if you want a union of resultsets, use ... UNION.
Using OR in a condition is equivalent to UNION (because the UNION operator is the relational algebra equivalent of logical disjunction), but it requires the scope of the involved conditions to be identical.
In this case, this is impossible because a HAVING condition applies not to the table mentioned in the SELECT, but instead to an intermediate table that is "silently" created by the GROUP clause. This is inevitably so because things like AVG,SUM,... only make sense if it is also determined which set of rows must be used to compute the AVG,SUM,... over, and that is what the GROUP BY specification does.
EDIT
In SQL, UNION comes in distinct flavours, UNION DISTINCT and UNION ALL. One eliminates duplicates, the other won't. If you want the exact same behaviour as OR, you'll obviously need the one that eliminates duplicates from its result set.

GROUP BY and ORDER BY on different columns

I want to execute a query on POSTGRESQL server whose structure is as below:
SELECT col1, SUM(col2) GROUP BY col1 ORDER BY colNotInSelect;
I have tried to include the colNotInSelect in the GROUP BY clause but since it is a column with a distinct value, it defeats the purpose of using GROUP BY in the first place.
Any help is appreciated.
You cannot order by that column because it potentially has many values for each value of col1.
However you can apply an aggregate function to the column, and order by that.
for example:
SELECT col1,
SUM(col2)
GROUP BY col1
ORDER BY MIN(colNotInSelect);
You question actually makes no sense because rows are grouped by col1 so there is no colNotInSelect in the grouped rows. Try to aggregate colNotInSelect before ordering, for example:
SELECT col1, SUM(col2), AVG(colNotInSelect) as col3 GROUP BY col1 ORDER BY col3;
If it isn't fit your need, maybe you should clarify what you're doing.