adding count( ) column on each row - sql

I'm not sure if this is even a good question or not.
I have a complex query with lot's of unions that searches multiple tables for a certain keyword (user input). All tables in which there is searched are related to the table book.
There is paging on the resultset using LIMIT, so there's always a maximum of 10 results that get withdrawn.
I want an extra column in the resultset displaying the total amount of results found however. I do not want to do this using a separate query. Is it possible to add a count() column to the resultset that counts every result found?
the output would look like this:
ID Title Author Count(...)
1 book_1 auth_1 23
2 book_2 auth_2 23
4 book_4 auth_.. 23
...
Thanks!

This won't add the count to each row, but one way to get the total count without running a second query is to run your first query using the SQL_CALC_FOUND_ROWS option and then select FOUND_ROWS(). This is sometimes useful if you want to know how many total results there are so you can calculate the page count.
Example:
select SQL_CALC_FOUND_ROWS ID, Title, Author
from yourtable
limit 0, 10;
SELECT FOUND_ROWS();
From the manual:
http://dev.mysql.com/doc/refman/5.1/en/information-functions.html#function_found-rows

The usual way of counting in a query is to group on the fields that are returned:
select ID, Title, Author, count(*) as Cnt
from ...
group by ID, Title, Author
order by Title
limit 1, 10
The Cnt column will contain the number of records in each group, i.e. for each title.

Regarding second query:
select tbl.id, tbl.title, tbl.author, x.cnt
from tbl
cross join (select count(*) as cnt from tbl) as x
If you will not join to other table(s):
select tbl.id, tbl.title, tbl.author, x.cnt
from tbl, (select count(*) as cnt from tbl) as x

My Solution:
SELECT COUNT(1) over(partition BY text) totalRecordNumber
FROM (SELECT 'a' text, id_consult_req
FROM consult_req cr);

If your problem is simply the speed/cost of doing a second (complex) query I would suggest you simply select the resultset into a hash-table and then count the rows from there while returning, or even more efficiently use the rowcount of the previous resultset, then you do not even have to recount

This will add the total count on each row:
select count(*) over (order by (select 1)) as Cnt,*
from yourtable

Here is your answare:
SELECT *, #cnt count_rows FROM (
SELECT *, (#cnt := #cnt + 1) row_number FROM your_table
CROSS JOIN (SELECT #cnt := 0 AS variable) t
) t;

You simply cannot do this, you'll have to use a second query.

Related

How to use to functions - MAX(smthng) and after COUNT(MAX(smthng)

I don't understand why I can't use this in my code :
SELECT MAX(SMTHNG), COUNT(MAX(SMTHNG))
FROM SomeTable;
Searched for an answer but didn't find it in documentation about these aggregate functions.
Also I get an SQL-compiler error "Invalid column name "SMTHNG"".
You want to know what the maximum SMTHNG in the table is with:
SELECT MAX(SMTHNG) FROM SomeTable;
This is an aggregation without GROUP BY and hence results in one single row containing the maximum SMTHNG.
Now you also want to know how often this SMTHNG occurs and you add COUNT(MAX(SMTHNG)). This, however, does not work, because you can not aggregate an aggregate directly.
This doesn't work either:
SELECT ANY_VALUE(max_smthng), COUNT(*)
FROM (SELECT MAX(smthng) AS max_smthng FROM sometable) t;
because the sub query only contains one row, so it's too late to count.
So, either use a sub query and select from the table again:
SELECT ANY_VALUE(smthng), COUNT(*)
FROM sometable
WHERE smthng = (SELECT MAX(smthng) FROM sometable);
Or count per SMTHNG before looking for the maximum. Here is how to get the counts:
SELECT smthng, COUNT(*)
FROM sometable
GROUP BY smthng;
And the easiest way to get the maximum from this result is:
SELECT TOP(1) smthng, COUNT(*)
FROM sometable
GROUP BY smthng
ORDER BY COUNT(*) DESC;
First of all, please read my comment.
Depending on what you're trying to achieve, the statement have to be changed.
If you want to count the highest values in SMTHNG field, you may try this:
SELECT T1.SMTHNG, COUNT(T1.SMTHNG)
FROM SomeTable T1 INNER JOIN
(
SELECT MAX(SMTHNG) AS A
FROM SomeTable
) T2 ON T1.SMTHNG = T2.A
GROUP BY T1.SMTHNG;
use cte like below or subquery
with cte as
(
select count(*) as cnt ,col from table_name
group by col
) select max(cnt) from cte
you can not use double aggregate function at a time on same column

Issue using not exist in SQL

Not exist is not working.
I have a query which is fetching 10k rows... now there are 237 rows which I do not want to be retrieved in my final result but when I am using not exist it is fetching the same no. of rows that is 10k I have used the following query:
Select bu_name,
person_num,
name,
f_config_id,
ass_the
from x_asig_table
where not exist ((select 1
from
(select XXH.x_asig_table.*,
count(*) over (partition by bu_name, person_num, name) as c
from XXH.x_asig_table) t
where c > 1);
The sub-query is not correlated with the main query, i.e. it doesn't matter what row you look at in the main query, the subquery will always give you the same result. So either you get all rows or none. It is not possible with this query to get some rows and others not.
Add criteria to your subquery that relates it to the main query to solve the problem.
You need to connect back to the outer query. Something like this (also simplified your query, untested, but should work):
Select bu_name,
person_num,
name,
f_config_id,
ass_the
from x_asig_table X
where not exist (
SELECT NULL
FROM x_asig_table Y
GROUP BY bu_name,person_num, name
WHERE X.bu_name = Y.bu_name
AND X.person_num = Y.person_num
AND X.name = Y.name
HAVING COUNT(1) > 1
)
You appear to be trying to find only those rows where there is a single row per combination of bu_name, person_num and name (although the question is rather unclear what your intents are). If so, then you can do it without using EXISTS like this:
SELECT bu_name,
person_num,
name,
f_config_id,
ass_the
FROM (
SELECT bu_name,
person_num,
name,
f_config_id,
ass_the,
COUNT(1) OVER ( PARTITION BY bu_name, person_num, name ) AS cnt
FROM x_asig_table
)
WHERE cnt = 1;

Count number of rows without using any aggregate functions

I need to count the number of rows in a table with a single SQL query.
That query should not contain any aggregate function like COUNT.
I'm a little surprised nobody has mentioned this yet:
EXEC sp_spaceused #objname = N'MyTable', #updateusage = 'TRUE'
This will, among other things return the current count of records in the table.
This would also work in most cases:
SELECT rows
FROM sys.partitions
WHERE index_id IN (1,0)
AND object_id = OBJECT_ID(N'MyTable')
The ROW_NUMBER ranking function will do the trick in a single query without using an aggregate function:
SELECT TOP 1 Row
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY SomeColumn) Row
FROM YourTable) output
ORDER BY Row DESC
Easy way:
DECLARE #i INT = 0
SELECT #i = #i + 1
FROM <WHAT EVER>
SELECT #i AS RC
Fast, effective and no need for all sorts of sub queries as it requires only one run through the data :)
An over() function solves the problem.
select Column1,Column2, count(*) over() as testColumn from tablename
COUNT THE NUMBER OF ROWS OF ITEMS.
SELECT MAX(EMPLOYEE_ID) FROM (SELECT ROW_NUMBER() OVER(ORDER BY EMPLOYEE_ID DESC) EMPLOYEE_ID FROM MYCODE);
Since "single SQL query" has proven to be a loose requirement, consider what I thought of immediately...but dismissed as unfit (as I indicated in comments on #AllenSHansen's answer):
SELECT 1 FROM YourTable;
SELECT ##ROWCOUNT;
try this
SELECT MAX(Row) FROM
(SELECT ROW_NUMBER() OVER(ORDER BY anycolumn DESC) Row FROM tablename) output
but what is stopping you use Count()? prefer to use count().
Here you may find one way to do that:
SELECT
Total_Rows= SUM(st.row_count)
FROM
sys.dm_db_partition_stats st
WHERE
object_name(object_id) = 'Mytable' AND (index_id < 2)
Find a good discussion on it here.
There are to ways to count records in a table:
Let the dbms count. You'd use an aggregate function for this, e.g. select count(*) from mytable;
You count. I.e. execute select * from mytable; and then count the records shown.
I would suggest the former method, but you seem to want to use the latter. Enjoy.
Using ROW_NUMBER(), you will get the total number of rows in a table without using aggregate functions as the 2-step example below demonstrates.
1) Table & Data Setup
Example:
Create Table Dted (id int , name Varchar(20))
Insert into dted values (1,'aaa'),(2,'bbb'),(3,'ccc')
Select * from dted
Output:
id name
1 aaa
2 bbb
3 ccc
2) Total Number of Rows
Example:
select top 1 ROW_NUMBER() over (order by id) as TotRows from dted order by TotRows desc
Output:
TotRows
3

Adding count in select query

I am trying to find a query that would give me a count of another table in the query. The problem is that I have no idea what to set where in the count part to. As it is now it will just give back a count of all the values in that table.
Select
ID as Num,
(select Count(*) from TASK where ID=ID(Also tried Num)) as Total
from ORDER
The goal is to have a result that reads like
Num Total
_________________
1 13
2 5
3 22
You need table aliases. So I think you want:
Select ID as Num,
(select Count(*) from TASK t where t.ID = o.ID) as Total
from ORDER o;
By the way, ORDER is a terrible name for a table because it is a reserved work in SQL.
You can do it as a sub query or a join (or an OVER statement.)
I think the join is clearest when you are first learning SQL
Select
ID as Num, count(TASK.ID) AS Total
from ORDER
left join TASK ON ORDER.ID=TASK.ID
GROUP BY ORDER.ID

SELECT *, COUNT(*) in SQLite

If i perform a standard query in SQLite:
SELECT * FROM my_table
I get all records in my table as expected. If i perform following query:
SELECT *, 1 FROM my_table
I get all records as expected with rightmost column holding '1' in all records. But if i perform the query:
SELECT *, COUNT(*) FROM my_table
I get only ONE row (with rightmost column is a correct count).
Why is such results? I'm not very good in SQL, maybe such behavior is expected? It seems very strange and unlogical to me :(.
SELECT *, COUNT(*) FROM my_table is not what you want, and it's not really valid SQL, you have to group by all the columns that's not an aggregate.
You'd want something like
SELECT somecolumn,someothercolumn, COUNT(*)
FROM my_table
GROUP BY somecolumn,someothercolumn
If you want to count the number of records in your table, simply run:
SELECT COUNT(*) FROM your_table;
count(*) is an aggregate function. Aggregate functions need to be grouped for a meaningful results. You can read: count columns group by
If what you want is the total number of records in the table appended to each row you can do something like
SELECT *
FROM my_table
CROSS JOIN (SELECT COUNT(*) AS COUNT_OF_RECS_IN_MY_TABLE
FROM MY_TABLE)