SUM of all fields in one column - sql

Im trying to calculate the SUM of all the numbers in one column.
The column name is 'Units' the type in integer.
This should work?
cmd3 = New OleDbCommand("SELECT SUM(Units) FROM tblJobs WHERE BookedOut = NULL AND HoldDate = NULL ", con)
lblLiveUnits.Text = cmd3.ExecuteNonQuery()
Thank you

Your query is not correct, you do not want to make something =NULL you should use IS NULL:
SELECT SUM(Units) As TotalUnits
FROM tblJobs
WHERE BookedOut IS NULL
AND HoldDate IS NULL
Then in your code you will use ExecuteScalar:
Int32 lblLiveUnits = 0;
cmd3 = New OleDbCommand("SELECT SUM(Units) As TotalUnits FROM tblJobs WHERE BookedOut IS NULL AND HoldDate IS NULL ", con);
lblLiveUnits = cmd3.ExecuteScalar()

Related

Efficient stats from Access DB

I am pulling stats from Access DB and using the following:
'''
countBP = Convert.ToInt32(New OleDbCommand(commandBP.ToString, con).ExecuteScalar)
countWP = Convert.ToInt32(New OleDbCommand(commandWP.ToString, con).ExecuteScalar)
countHP = Convert.ToInt32(New OleDbCommand(commandHP.ToString, con).ExecuteScalar)
'''
where:
'''
command = ""SELECT COUNT(*) FROM Employees WHERE Archived = 'N' AND ID > 2"
commandBP = command.ToString + " AND Ethnic = 'B' AND EmployeeType = 1"
commandWP = command.ToString + " AND Ethnic = 'W' AND EmployeeType = 1"
commandHP = command.ToString + " AND Ethnic = 'H' AND EmployeeType = 1"
'''
My question is; is this efficient? I am pulling 20+ stats separately, and it seems to be taking more and more time to load as the DB grows. I wondering if "SELECT * FROM Employees" to a dataset and then filter would be a better approach?
The only variable part of your query is the Ethnic field. This suggest to use the Group By clause on that field
command = "SELECT Ethnic, COUNT(*) FROM Employees
WHERE Archived = 'N' AND ID > 2 AND EmployeeType = 1
GROUP BY Ethnic"
Now this reduces the database calls to just one call and you can retrieve your data with
Dim data as Dictionary(Of String, Int32) = new Dictionary(Of String, Int32)()
OleDbCommand cmd = New OleDbCommand(command, con)
OleDbDataReader reader = cmd.ExecuteReader();
while(reader.Read())
data(reader.GetString(0)) = reader.GetInt32(1)
End While
At this point you can get the count values from your dictionary
Dim countBP as Integer
data.TryGetValue("B", countBP)
....
Notice that you should use the TryGetValue method to extract values from the database because if there are no record for Ethnic = "B" there will be no entry in the dictionary for the Key "B" but TryGetValue will leave the CountBP initialized with its default to zero.

SQL query in Excel table

I am running a query using OleDbCommand in a database in Excel, containing the following columns:
name, city, inhabitants
My code:
Cmd = new OleDbCommand();
Cmd.Connection = Conn;
Cmd.Parameters.AddWithValue("#city", city);
Cmd.CommandText = "Select City, count(habitants) as h from [Sheet1$] where city = #city group by city";
var Reader = await Cmd.ExecuteReaderAsync();
I get this error:
OleDbException: You tried to execute a query that does not include the specified expression 'city' as part of an aggregate function.
Why does this error appear if it contains the city column?
You can probably work around this error by adding GROUP BY to your query:
Cmd.CommandText = "Select City, count(habitants) as h from [Sheet1$] where city=#city group by City";
Use the FIRST() function for the city:
Cmd.CommandText = "SELECT FIRST(city) AS city, COUNT(habitants) AS h FROM [Sheet1$] WHERE city=#city GROUP BY city";

Dynamic Calculated Field in VBA Access

I'm trying to add a field into an existing table. The field is calculated using two variables 'myPrice', which is the price of a record at a certain date, and 'previousPrice', which is the price of the same part from the first record, only a from the month previous. I'm using a loop to iterate through the entire recordset of prices, thereby altering the two variables each time. My code is as follows:
Function priceDifference()
Dim currentPrice As Currency
Dim previousPrice As Currency
Dim recordDate As Date
Dim previousDate As Date
Dim dbsASSP As DAO.Database
Dim priceTable As DAO.TableDef
Dim diffFld As DAO.Field2
Dim rstCurrentPrice As DAO.Recordset
Dim rstPreviousPrice As DAO.Recordset
Dim PN As String
Set dbsASSP = CurrentDb
strSQL = "SELECT * FROM qryPrice"
Set rstCurrentPrice = dbsASSP.OpenRecordset(strSQL, dbOpenDynaset)
Set priceTable = dbsASSP.TableDefs("tblPrice")
Set diffFld = priceTable.CreateField("Difference", dbCurrency)
If Not (rstCurrentPrice.EOF) Then
rstCurrentPrice.MoveFirst
Do Until rstCurrentPrice.EOF = True
PN = rstCurrentPrice![P/N]
recordDate = rstCurrentPrice![myDate]
previousDate = Format(DateAdd("m", -1, recordDate), "M 1 YYYY")
myPrice = rstCurrentPrice!Price
strPreviousSQL = "SELECT * FROM qryPrice WHERE [MyDate] = #" & previousDate & "# AND [Type] = 'Net Price' AND [P/N] = " & PN & ""
Set rstPreviousPrice = dbsASSP.OpenRecordset(strPreviousSQL, dbOpenDynaset)
myCodeName = rstCurrentPrice!CodeName
If DCount("[P/N]", "qryPrice", "[MyDate] = #" & previousDate & "# And [P/N] = " & PN) <> 0 Then
previousPrice = rstPreviousPrice!Price
Else
previousPrice = myPrice
End If
rstCurrentPrice.MoveNext
Loop
Else
MsgBox "Finished looping through records."
End If
diffFld.Expression = myPrice - previousPrice
rstCurrentPrice.Close
rstPreviousPrice.Close
priceTable.Fields.Append diffFld
End Function
Syntactically, it works. The calculated field, however, does not give me the correct values and I cannot figure out why, although I imagine it has something to do with the dynamic formula.
Any help is appreciated. Thanks!!
Your code can't work as you append a number to the field instead of a formula, but you should avoid calculated fields
Use a query:
SELECT
nPrice.[P/N],
nPrice.Price,
nPrice.MyDate,
oPrice.MyDate,
nPrice.Price-Nz(oPrice.Price,nPrice.Price) AS diff
FROM (
SELECT
[P/N],
Price,
MyDate,
Format(DateAdd("m",-1,MyDate),"yyyymm") as previousMonthYear
FROM
tblPrice) AS nPrice
LEFT JOIN (
SELECT
[P/N],
Price,
MyDate,
Format(MyDate,"yyyymm") AS monthYear
FROM
tblPrice) AS oPrice
ON
nPrice.[P/N] = oPrice.[P/N]
AND nPrice.previousMonthYear = oPrice.monthYear
This calculates the difference dynamic and you don't need to store it.
I assume there is max one price per month, otherwise you need to filter the subqueries or just calculate the difference to the last price before.
If the query is too slow ([P/N] and MyDate need an index) , you can still use it to update a field the table tblPrice, but this has to be updated every time a price is updated or inserted in tblPrice
I think you can avoid your code loop by using this query
SELECT A.qryPrice, A.MyDate, B.qryPrice, B.MyDate
FROM qryPrice A LEFT OUTER JOIN qryPrice B
ON A.[P/N] = B.[P/N]
AND B.MyDate = DATEADD(month, -1, A.MyDate)

Writing SQL statement to select from multiple rows

This might be a silly question to ask. I will appreciate any kind of help.
I'm trying to write a query that count the number of rows based on the logic as below:
count no rows where username = #username and friendsname = #friendsname and username = #friendsname and #friendsname = #username where status = 0
consider the table in the diagram below:
The query should return 1 since id '18' and id '20' have reciprocal values. How will this query be written?
I have written the query as follows which doesn't work:
bool flag = false;
StringBuilder query = new StringBuilder();
query.Append("SELECT Count(id) from friends where username=#username AND friend_username=#friend_username AND username = #friend_username AND friend_username = #username");
query.Append(" AND status=0");
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("#username", username));
cmd.Parameters.Add(new SqlParameter("#friend_username", friendusername));
if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
flag = true;
}
}
return flag;
If I'm not mistaken you're trying to count rows given a specific #username and #friendusername that have reciprocal values based on your conditions.
Below query should help, though - I have not tested it in action!
SELECT COUNT(*) as reciprocal_values_no
FROM table_name tbl1
WHERE
username = #username
AND friend_username = #friendusername
AND status = 0
AND EXISTS (
SELECT 1 FROM table_name tbl2 WHERE tbl1.username = tbl2.friend_username AND tbl1.friend_username = tbl2.username )
try this
select username,friend_username,status, count(*)
from table_name
group by username,friend_username,status
having count(*) > 1

How to write correct grammar of sql query statement in asp.net

now I'm facing a problem: I want to get a total number from result='yes' and 'no' from database.
Actually I try a sql query in my sql server studio is working correctly, but when I place the same sql query in the
code of asps.cs, nothing happens, I don't know why. Hope someone can help me to find the problem.
The code as below:
String query_risk1 = "SELECT (SELECT count(result) FROM [rampDB].[dbo].[Answers] WHERE [result]='yes' AND [company] = #deName1 AND [questionID] BETWEEN '1.1a' AND '1.1e' )+(SELECT count(result) FROM [rampDB].[dbo].[Answers] WHERE [result]='no' AND [company] = #deName1 AND [questionID] BETWEEN '1.1a' AND '1.1e')";
DataSet ds_risk = new DataSet();
SqlDataAdapter riskadapter1 = new SqlDataAdapter(query_risk1, sqlConn);
riskadapter1.SelectCommand.Parameters.Add(new SqlParameter("#deName1", site_name));
DataTable risk_table1 = new DataTable();
riskadapter1.Fill(risk_table1);
ds_risk.Tables.Add(risk_table1);
risk_table1 = ds_risk.Tables[0];
grid2.DataSource = ds_risk;
grid2.DataBind();
Try this query
SELECT SUM(CASE WHEN [result] = 'yes' OR [result] = 'no' THEN 1 ELSE 0 END) As Result
FROM [rampDB].[dbo].[answers]
WHERE [company] = #deName1 AND [questionid] BETWEEN '1.1a' AND '1.1e'
May be something like this
String query_risk1 = "SELECT SUM(CASE WHEN [result] = 'yes' OR [result] = 'no' THEN 1 ELSE END) As Result FROM [rampDB].[dbo].[answers] WHERE [company] = #deName1 AND [questionid] BETWEEN '1.1a' AND '1.1e'";
DataSet ds_risk = new DataSet();
SqlDataAdapter riskadapter1 = new SqlDataAdapter(query_risk1, sqlConn);
riskadapter1.SelectCommand.Parameters.Add(new SqlParameter("#deName1", site_name));
DataTable risk_table1 = new DataTable();
riskadapter1.Fill(risk_table1);
ds_risk.Tables.Add(risk_table1);
risk_table1 = ds_risk.Tables[0];
grid2.DataSource = ds_risk;
grid2.DataBind();
your query is similar to this query:
SELECT count(result)
FROM [rampDB].[dbo].[Answers]
WHERE ([result]='yes' OR [result]='no') AND
[company] = #deName1 AND
[questionID] BETWEEN '1.1a' AND '1.1e'
and finally if you use this query you can tru ExecuteScaler() method to get return value of query:
SqlConnection sqlCon = new SqlConnection("YOUR SQL CONNECTIONSTRING");
SqlCommand sqlCom = new SqlCommand("THE QUERY", sqlCon);
sqlCom.Parameters.AddWithValue("#deName1", "SOME VALUE");
sqlCon.Open();
int count = (int)sqlCom.ExecuteScaler();
sqlCon.Close();