I want to get the count of rows of a table.
cmd.CommandText = "SELECT COUNT(*) FROM (SELECT * FROM (SELECT * FROM EMPLOYEE ))";
Records = int.Parse(cmd.ExecuteScalar().ToString());
even if there is 1 row in employee table, Records always have value 0.
why ExecuteScalar() returns 0?
What you are trying to calculate is the number of rows in the EMPLOYEE table, therefore Pranav and Vinod are right. But assuming you try to simplify your situation just to point directly to your problem, I would say that you need to give names to your temporary tables like this:
cmd.CommandText = "SELECT COUNT(*) FROM (SELECT * FROM (SELECT * FROM EMPLOYEE ) as T1) as T2";
Records = int.Parse(cmd.ExecuteScalar().ToString());
That should do the trick.
One additional suggestion is not to use count(0); instead use count(0). '*' brings all data in the view; which is an unnecessary performance decrement for count function.
It returns 0 because your SQL request isn't valid.
You should always try your requests directly against your database (for instance using SQL Server Management Studio if you are using SQL Server) before writing them in your code. You would have seen it doesn't return anything because it has a syntax error.
If you want to use nested SELECT * FROM as you wrote, here's the valid SQL request that will return what you expected:
SELECT COUNT(*) FROM (SELECT * FROM (SELECT * FROM EMPLOYEE ) AS Foo1 ) AS Foo2
In any case, as all other answers have noted, this doesn't make much sense, and must be replaced by:
SELECT COUNT(*) FROM EMPLOYEE
Try this:
cmd.CommandText = "SELECT COUNT(*) FROM EMPLOYEE";
int Records = (int)cmd.ExecuteScalar();
That should return the number of rows in the EMPLOYEE table.
To double check, use the SQL management studio to execute the same code against your SQL server and see what the result is. Is it possible that your application is configured to point a different database to the one that you are viewing?
Just say:
cmd.CommandText = "SELECT COUNT(*) FROM EMPLOYEE";
Records = int.Parse(cmd.ExecuteScalar().ToString());
Try this:
cmd.CommandText = "SELECT COUNT(*) FROM EMPLOYEE"
Int record=(Int32)cmd.Executescalar();
Related
I have a code where i do sql query by casting the table model like this:
string sql = string.Format("SELECT * FROM {0}...", tableName...);
and then:
IEnumerable<T> r = dbConn.Connection.Query<T>(sql...);
the thing is if i want to get total rowsCount(of course i can get count on the "r" but if there is a where clause its not possible because i want total count) i have to another query without where.
so i want to remove the second query. i did this in sql query to get rowsCount:
string sql = string.Format("SELECT *, count(*) over() rowsCount FROM {0}...", tableName...);
i can get the rowsCount with this query but since neither one of models has rowsCount i cant access it, is there any suggestions on how i should do it?
Edit:
first query has paging filter by using offset and limit, so i want totalcount not the count of filtered query.
I'm looking to see if there is a way to not use two seperate queries, and get results and also rowsCount by just one query.
You will have to do 2 SQL queries.
Nothing stopping you running them in one SQL block or calling a stored proc with output parameters. So you don't have to make 2 calls but you will need 2 queries at least.
https://www.sqlservertutorial.net/sql-server-stored-procedures/stored-procedure-output-parameters/
If you are worried about performance of a total count just make sure you have an index on the smallest column in that table and it should be mega fast.
The below example return a dataset and an output in one call
DROP PROCEDURE IF EXISTS dbo.DataSetAndOutput
GO
CREATE PROCEDURE dbo.DataSetAndOutput
#YourId BIGINT,
#CountRecords INT OUTPUT
AS
BEGIN
SELECT * FROM YourTable
WHERE Id = #YourId
SET #CountRecords = (SELECT COUNT(YourId) FROM YourTable)
END
GO
-- Test the output
DECLARE #ResultCount INT
EXEC dbo.DataSetAndOutput #YourId= 252452, #CountRecords = #ResultCount OUTPUT
SELECT #ResultCount AS TheCount
I am trying to use a two line query to a mysql database like this with C#:
set #var = 1; select id from table where id = #var`;
Executing this in C# does not give any error, the reader has columns, but don't have rows in it, so, no data is retrieved.
Running the same queries in the workbench retrieve the expected data.
Running one query to calculate the variable and other to use it replaced works.
I want to use a variable to store references and use it to filter queries that provide an union.
SET #my_value = (select min(id) from (select id from datatable limit 2000) as a);
and a complex select query, that i can resume in:
select * from
datatable as a
left join (
(select databalt2 where id > #my_value) as ba union
(select datatable3 where id > #my_value) as bb) as b
on a.id = b.id
where a.id > #my_value;
The datareader should obtain the results, but instead reports that it has no rows, but has the correct amount of columns.
And, obviously, shows no results, where it should.
Edit 1: C# code
string query = #"
SET #`my_value` = (select min(id) from (select id from datatable limit 2000) as a);
select * from
datatable as a
left join (
(select databalt2 where id > #`my_value`) as ba union
(select datatable3 where id > #`my_value`) as bb) as b
on a.id = b.id
where a.id > #`my_value`;
";
try
{
MySqlCommand command = Connection.CreateCommand();
MySqlDataReader reader;
command.CommandTimeout = commandTimeout;
command.CommandText = query;
reader = command.ExecuteReader();
}
catch (Exception ex)
{
}
These queries using local variables are possible, the local variable has to be inside like #`var`, because it can be identifyied as a local parameter.
I was missing a in a local variable call. So ... a problem between the screen and the chair!
How would I go about doing this say I have a bunch of registers and they have a terminal id = 4741 and I only want the very last record of that day. I am using SQL Server 2008 R2.
SELECT TOP 1000
[id]
,[data_atualizacao]
,[direcao]
,[velocidade]
,[latitude]
,[longitude]
,[nivel_bateria]
,[enum_status_gps]
,[id_terminal]
FROM
[TecnologiaGPS_V2].[dbo].[posicao_historico_terminal_82015]
WHERE
id_terminal = 4741
ORDER BY
data_atualizacao ASC
But say that above query returns the following I only want however the last time the 19:57:58 one i thought order by would have been enough but it just brings me them in ascending order.
id_terminal 19:57:05
id_terminal 19:57:15
id_temminal 19:57:58
This is how I am getting my data back in c#
using (SqlCommand cmd = new SqlCommand("SELECT * FROM motorista where id = " + driverId +" order_by data_atualizacao", connection))
{
connection.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Check is the reader has any rows at all before starting to read.
if (reader.HasRows)
{
// Read advances to the next row.
while (reader.Read())
{
motorista motorist = new motorista();
// To avoid unexpected bugs access columns by name.
motorist.id = reader.GetInt32(reader.GetOrdinal("id"));
motorist.nome = reader.GetString(reader.GetOrdinal("nome"));
motorist.numero_registro = reader.GetString(reader.GetOrdinal("numero_registro"));
morotistList.Add(motorist);
}
return morotistList.ToList();
}
}
}
So my question is how do I get the very most recent time stamp and also is my code sufficient when I would be paging through a record set of six million entries. Even though I will always have the terminal id to pass to the query.
Select top 1 *
from TecnologiaGPS_V2
where id_terminal = 4741
order by data_atualizacao desc
select
[id], [data_atualizacao], [direcao], [velocidade],
[latitude], [longitude], [nivel_bateria],
[enum_status_gps],[id_terminal]
from
(select
[id],
row_number() over(partition by id order by data_atualizacao desc) rn,
[data_atualizacao], [direcao], [velocidade],
[latitude], [longitude], [nivel_bateria],
[enum_status_gps], [id_terminal]
from
[TecnologiaGPS_V2].[dbo].[posicao_historico_terminal_82015]
where
id_terminal = 4741) t
where
t.rn = 1
You can use a row_number window function to get the latest record for each id.
Rather than sorting the data you could also use and aggregate as well.
SELECT *
FROM
[TecnologiaGPS_V2].[dbo].[posicao_historico_terminal_82015]
WHERE
id_terminal = 4741
AND data_atualizacao = (SELECT MAX (data_atualizacao) FROM [TecnologiaGPS_V2].[dbo].[posicao_historico_terminal_82015] as subquery
WHERE id_terminal = subquery.id_terminal)
Doing an order by can cause extra work by the database server. Sorts can be extremely expensive based on the data set size. While you can also rely on an index to also keep it sorted for you, you are going to pay in index maintenance. Sql server is good at aggregations, this may perform better overall. Also, based on your table definition you are guaranteed 1 row.
select top 1 * from tablename where [condition] order by [column] desc;
to check run the each query one by one.
SELECT * FROM Orders where EmployeeID = 4 ;
SELECT top 1 * FROM Orders where EmployeeID = 4 order by OrderDate desc;
in
http://www.w3schools.com/sql/trysql.asp?filename=trysql_func_first&ss=-1
I am presently pulling two long values from my database with two selects:
// We need the number of users and the total bandwidth
long numUsers, totalBandwidth;
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select count(*) from [User] where [User].CompanyId = #CompanyId";
DbUtilities.AddParam(cmd, "#CompanyId", id);
numUsers = (long)(decimal)cmd.ExecuteScalar();
}
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select sum(BandwidthThisMonth) from [User] where [User].CompanyId = #CompanyId";
DbUtilities.AddParam(cmd, "#CompanyId", id);
totalBandwidth = (long)(decimal)cmd.ExecuteScalar();
}
I think logically this can be a single select that returns two numbers. But everything I've tried has given me errors. Can this be done?
select count(*) as count_all,
sum(BandwidthThisMonth) as sum_BandwidthThisMonth
from [User]
where [User].CompanyId = #CompanyId
but you'll get two columns back instead of one scalar. so you'll need to handle that...
If you want them in the same column, you can use a union. This scans the table 2 times, so not as efficient.
select "count" as key
, count(*) as value
from [User]
where [User].CompanyId = #CompanyId
union all
select "sum_BandwidthThisMonth" key
, sum(BandwidthThisMonth) as value
from [User]
where [User].CompanyId = #CompanyId
Use union all if you don't want a sort. Union does a sort. Not a big deal with 2 rows, but...
I'm trying to write a windows forms app in C# .Net 4 it connects to a SQL Server 2008 database and I want to Select highest number from a table where the number is stored as string!
string SQL = "select MAX(CONVERT(int, myField)) from myTable where myCode = '" + theCust + "'";
I have also tried Max(CAST(myField as Int)) in the select statement but both fail to return anything even though the Database has for the theCust two rows with 10001 and 10002. The Error i Get is "Enumeration yielded no results"
What am I doing wrong?
I'm using the in built System.Data.SqlClient and if I just do a
string SQL = "select myField from myTable where myCode = '" + theCust + "'";
it returns both numbers as strings. I know I could sort them in code but if the Database gets large that would not be a good approach!
I just tried it again with an int Field in the db and still got the same error! Is Max the wrong thing to be using?
You can try it like this:
SELECT TOP 1 CAST(MyColumn AS int) AS TheMax
FROM MyTable
ORDER BY TheMax DESC
So (using the sloppy method, always paramaterize!)
String sql = "SELECT TOP 1 CAST(MyColumn AS int) AS TheMax FROM MyTable WHERE MyParam = '" + param + "' ORDER BY TheMax Desc";
//Fill DataAdapter/DataReader etc.
Have this function in your database(s):
CREATE FUNCTION dbo.IsAllDigits (#MyString VARCHAR(8000))
RETURNS TABLE AS
RETURN (
SELECT CASE
WHEN #MyString NOT LIKE '%[^0-9]%'
THEN 1
ELSE 0
END AS IsAllDigits
)
because it's better than the in-build ISNUMERIC() in T-SQL.
Then you can use this query to get set of strings that convert to integer types without errors, and filter them like with TOP 1.
SELECT TOP 1 MyColumn AS TheMax
FROM MyTable
WHERE IsAllDigits(MyColumn)=1
ORDER BY MyColumn DESC