count the specific record from access in vb.net - vb.net

So i am making a voting program but i am stuck right now.
I have searched for solutions and i have followed them precisely but still no result.
Basically i want to count the total occurrence for each specific record from access in visual basic.
For example i have the candidate number 1 voted by three persons and candidate 2 by 7 persons, i want to show this voting result in a textbox but somehow it always shows me the wrong number
So here is my code:
Dim TotalVotes As Integer
myCommand = New OleDbCommand("SELECT CandidateNumber, COUNT (*) FROM Student_Voting GROUP BY CandidateNumber", dbconn)
TotalVotes = myCommand.ExecuteScalar
NovTextBox.Text = TotalVotes
myCommand.Dispose()
myReader.Close()
This query here gives a result of the first candidate number not the total votes for selected candidate number:
SELECT CandidateNumber, COUNT (*) FROM Student_Voting GROUP BY CandidateNumber
I have tried this too but still wrong result:
SELECT COUNT(CandidateNumber) AS NoVotes FROM Student_Voting GROUP BY CandidateNumber
I don't know what's the problem here, it's suppose to be simple but yet.
If anyone could help i'd very much appreciate it.
Thanks in advance

First of all, the initial query you're running would return more than one record if you had more than one candidate. ExecuteScaler returns only the first column of the first row.
The question is, do you want all of the records or do you just want one person's record? If you just want one person's record you'll need add a WHERE clause to your sql statement to specify on that candidate.
If you want all of the records it would look something like this:
Using myCommand = New OleDbCommand("SELECT CandidateNumber, COUNT (*) AS CountValue FROM Student_Voting GROUP BY CandidateNumber", dbconn)
Using dr = myCommand.ExecuteReader
' Loops over all the canidate counts one by one.
While dr.Read
Dim totalVotes As Integer = CInt(dr("CountValue"))
Dim candidateNumber As String = dr("CandidateNumber")
End While
End Using
End Using
If you want only one record then you can use ExecuteScaler something like this:
Using myCommand = New OleDbCommand("SELECT COUNT (*) AS CountValue FROM Student_Voting WHERE CandidateNumber = #CandidateNumber GROUP BY CandidateNumber", dbconn)
myCommand.Parameters.Add("#CandidateNumber", OleDbType.VarChar).Value = "1"
Dim totalVotes = CInt(myCommand.ExecuteScalar)
End Using
I don't know the actual types in your database so you would need to tweak the OleDbType to fit your table setup and perhaps some of the casts.

Related

Filtering SQL data into multiple DataTables in a single DataSet

This should be simple, but it's escaping me right now as I have not written in VB in over a decade.
I have a stored procedure that gets a list of students and their assigned homeroom teacher.
Very basic - just the three columns: FirstName, LastName, Teacher.
What I need is to load the data into a DataSet where each Teacher has their own DataTable filled with the students assigned to them.
Sample data:
So in the example above, I would end up with 3 DataTables named Adams, Taggert and Dublin, each populated with the students associated with them all in a single DataSet in such a way that I could call the data with:
For Each dr As DataRow In ds.Tables("Taggert").Rows
' Do something with dr("FirstName").ToString
Next
Any help would be appreciated.
I ultimately used elements from both answers to find a solution. I ended up using DataViews to create the tables, and added them into the new DataSet. It works perfectly. It iterates through every record, but for the few hundred students it handles, it's actually quite
efficient. Thanks for the comments.
For Each row As DataRow In ds.Tables(0).Rows
Dim Teacher As String = row("Teacher").ToString()
If Not dsOutput.Tables.Contains(Teacher) Then
Dim dvStudents = ds.Tables(0).DefaultView
dvStudents.RowFilter = "Teacher = '" & Teacher & "'"
Dim subTable As New DataTable(Teacher)
subTable = dvStudents.ToTable(Teacher)
dsOutput.Tables.Add(subTable)
End If
Next
old_datatable with all teachers , i will declare this but you use your own
Dim old_datatable As New DataTable
Dim new_dataset As New DataSet
For Each row As DataRow In old_datatable.Rows
Dim teacher As String = row("Teacher")
If new_dataset.Tables.Contains(teacher) = False Then
Dim new_datatable As New DataTable
new_dataset.Tables.Add(new_datatable)
End If
new_dataset.Tables(teacher).Rows.Add(row)
Next
For Each dr As DataRow In new_dataset.Tables("Taggert").Rows
' Do something with dr("FirstName").ToString
Next

Access SQL Randomizer Not working as intended

I'm using the below mentioned code to select a record ID from an Access Database that wasn't already selected in the last day and add it to an array.
The general goal is that a record that matches the initial "Difficulty" criteria will be retrieved so long as either the record was never selected before OR the record wasn't chosen in the last 2 days. After the loop is done, I should have x amount of unique record ID's and add those onto an array for processing elsewhere.
Private Function RetrieveQuestionID(questionCount As Integer)
' We're using this retrieve the question id's from the database that fit our arrangements.
Dim intQuestArray(0 To questionCount) As Integer
Dim QuestionConnection As New OleDb.OleDbConnection("PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source = |DataDirectory|\Database\MillionaireDB.accdb;")
QuestionConnection.Open()
For i As Integer = 1 To intNoOfQuestions
'TODO: If there are no valid questions, pull up any of them that meets the difficulty requirement....
Dim QuestionConnectionQuery As New OleDb.OleDbCommand("SELECT Questions.QuestionID FROM Questions WHERE (((Questions.QuestionDifficulty)=[?])) AND (((Questions.LastDateRevealed) Is Null)) OR (Questions.LastDateRevealed >= DateAdd('d',-2,Date())) ORDER BY Rnd((Questions.QuestionID) * Time());", QuestionConnection)
QuestionConnectionQuery.Parameters.AddWithValue("?", intQuestionDifficulty(i - 1).ToString)
Dim QuestionDataAdapter As New OleDb.OleDbDataAdapter(QuestionConnectionQuery)
Dim QuestionDataSet As New DataSet
QuestionDataAdapter.Fill(QuestionDataSet, "Questions")
intQuestArray(i - 1) = QuestionDataSet.Tables("Questions").Rows(0).Item(0)
Dim QuestionConnectionUpdateQuery As New OleDb.OleDbCommand("UPDATE Questions SET Questions.LastDateRevealed = NOW() WHERE Questions.QuestionID = [?]", QuestionConnection)
QuestionConnectionUpdateQuery.Parameters.AddWithValue("?", intQuestArray(i - 1).ToString)
QuestionConnectionUpdateQuery.ExecuteNonQuery()
Next
QuestionConnection.Close()
Return intQuestArray
End Function
However, looping through the array will show that there are records are somehow being repeated even though the record updates during the loop.
Is there another way to loop through the database and pull up these records? I even attempted to move the .Open() and .Close() statements to within the For...Next loop and I'm given worse results than before.
As Steve wrote, the >= should be a < .
In addition, your WHERE clause is missing parentheses around the OR part.
It should be (without all unnecessary parentheses):
SELECT Questions.QuestionID
FROM Questions
WHERE Questions.QuestionDifficulty=[?]
AND ( Questions.LastDateRevealed Is Null
OR Questions.LastDateRevealed < DateAdd('d',-2,Date()) )
ORDER BY Rnd(Questions.QuestionID * Time());
Also have a look at How to get random record from MS Access database - it is suggested to use a negative value as parameter for Rnd().

Sort a Dataset in visualbasic

I don't know what i doing wrong. I have been on several forums trying to figure out how to sort a table in visual basic.
I have treid with and with out a dataview, but noting seams to work.
I have a logg that the user can do new inserts in. It has 3 columns. "Date", "Tool", "Comment".
When my VB application loads the program reads the table from a Access database and i get my sorting just fine by the sql phrase:
"select * from Logg ORDER BY Logg.Datum DESC"
After a user have uppdated the table i whant to sort it again. I have treid the following, but nothing happens. The order is the same whatever i do.
DS is my Dataset and dw my dataview, and "Datum" the column i whant to sort
DS.Tables("hela").DefaultView.Sort = "Datum DESC"
dw = DS.Tables("hela").DefaultView
For i = 0 To antal_poss - 1
LOGG(i, 0) = dw.Table.Rows(i).Item(3)
LOGG(i, 1) = dw.Table.Rows(i).Item(1)
LOGG(i, 2) = dw.Table.Rows(i).Item(4)
Next i
What am i doing wrong?
In your code you use the DataView to retrieve the Table and then the DataRows, but you extract them following the order on the DataTable.
You need to loop following the order of the DataView.
Something like this
Dim i As Integer = 0
For Each row As DataRowView in dw
LOGG(i, 0) = row.Item(3)
LOGG(i, 1) = row.Item(1)
LOGG(i, 2) = row.Item(4)
i += 1
Next i
Of course this assume that your LOGG array contains enough entries to accomodate every row retrieved. It is the same number of the rows in the DataTable

SQL: How to find if there is at least one record matching a condition

In one of my database tables, I want to know if there is atleast one record corresponding to a condition.
The query i wrote is
Count(*) from table where (condition)
And in my program, i can check whether the result is a non-zero value.
It works fine.
How can we optimize this? I dont want to wait till it finds the total count of records matching the condition.
SQL has exists which can be used for this. This will return 1 if the query returns a result, and 0 otherwise.
Select Case When Exists (<query>) Then 1 Else 0 End as X
SELECT TOP 1 1 AS found
FROM tablename
WHERE ...
Then check if the query returns a single row or not.
In this case engine will immediately return you result as soon as it finds the first row (assuming you don't add ORDER BY)
SqlCommand command = new SqlCommand("SELECT * FROM InsertProductTb", con);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
}

Count how often a foreign key occurs on another table and order by Ascending using Linq or Lambda

I have a database with two tables. Advertisements and Records as it's foreign key. I need to count how often a record of an advertisement occurs and order by ascending.
I am assuming that I have to use a combination of a join and a group by clause to accomplish this. It just isn't working the way I would like. Below is the code I have so far.
Public Shared Function SortAdsByHitCount() As DataTable
Dim dt As New DataTable
Try
Using context As New QREntities()
Dim ads = (From advertisement In context.QRAdvertisements
Join record In context.QRRecords On advertisement.adId Equals record.adId
Select advertisement.adId, advertisement.adRedirectUrl, advertisement.adType, advertisement.adData, count = record
Order By AdData Ascending).ToList()
'Dim ads = (From advertisement In context.QRAdvertisements
' Group advertisement.adId By advertisement.adId Into Group _
' Order By Group.Count() Ascending _
' Select Advertisement.AdRedirectUrl, Advertisement.AdType, Advertisement.AdData, Count = Group.Count()).ToList()
'Set the column headers and their accepted data types
dt.Columns.Add("adId", GetType(Integer))
dt.Columns.Add("adRedirectUrl", GetType(String))
dt.Columns.Add("adType", GetType(String))
dt.Columns.Add("adData", GetType(String))
dt.Columns.Add("hitCount", GetType(Integer))
For Each a In ads
dt.Rows.Add(a.adId, a.adRedirectUrl, a.adType, a.adData, a.Count)
Next
End Using
Catch ex As Exception
Return Nothing
End Try
Return dt
End Function
I basically need 4 rows from one table and I just include the count of the occurrence from the other. The advertisement datarow must know how many times it has been represented in the records table. So essentially, the gridview/listview would show the user a list of ads sorted by the frequency that that ad has been used.
Ex:
Advertisements
Ad id Ad Type Ad Date Ad Occurrence
1 Automotive 13/12/2012 10
2 Personal 10/12/2012 5
3 Retail 02/11/2012 3
Here you need to be using a grouping function so you have access to the .Count() extension of the group. To do this in static syntax would look like this:
Dim ads = (From advertisement In context.QRAdvertisements
Group Join record In context.QRRecords
On advertisement.adId Equals record.adId
Into records = Group
Select advertisement.adId, advertisement.adRedirectUrl, advertisement.adType, advertisement.adData, count = records.Count()
Order By AdData Ascending).ToList()