Visual Basic, filter on most occuring in Acces Databse

空扰寡人 提交于 2019-12-25 15:22:31

问题


I just started with programming in Visual Basic 2015. And I'm facing this problem:

I've made a database with Microsoft Acces 2010, the table I've made is called "notations" it looks like this.

As you can see I have already 10 records in my database with 4 columns. What I would like to do is filter the most occurring from the third column which is "categorie". With the result, I would like to create a document.

I really have no clue on how to get started with this so I really could use you help with this. If you need any additional information please let me know


回答1:


You need to split your problem in two steps:

  1. Get the most repeated value in your table
  2. Get the data related to that value.

I'll provide the SQL part of the solution:

For step 1:

select top 1 categorie, count(id) as n
from notations
group by categorie
order by n desc

This query will count the rows in your table, grouping them by categorie, and sorting them from greatest to smallest.

For step 2: You need to get the data from your table, using only the values you've retreived in your first query:

select notations.*
from notations
     inner join (select top 1 categorie, count(id) as n 
                 from notations 
                 group by categorie 
                 order by n desc) as a on notations.categorie = a.categorie

You can use this last query to get what you need.

I recommend you look for a good book or tutorial on SQL and Access.


After reading your comment, I'd like to explain a little bit about what's going on.

Note: What I'm about to explain assumes you have at least some knowledge of SQL (not any particular product, but the language). Also, consider that every RDBMS (Microsoft Access included) uses a particular dialect of SQL, so what works in Access may not work in other RDBMS (SQL-Server, MySQL, PostreSQL, Oracle, etcetera).

Let's dissect the query in "Step 1":

select               -- This is a SELECT query, so it will return rows.
    top 1            -- Return ONLY the firs row.
    categorie,       -- Show column "categorie".
    count(id) as n   -- This is an aggregate function: It will count
                     -- the values of column "Id", and will group them
                     -- by the columns defined in the GROUP BY clause;
                     -- we define an alias for this column using the keyword "AS".
from notations       -- The source of the data this query will return rows from.
group by categorie   -- All aggregate functions will be affected by the
                     -- GROUP BY clause; in this case, "count(id)" will be
                     -- grouped by "categorie".
order by n desc      -- Sort the rows from the greatest to the smallest value
                     -- of column "n" (which is the alias for "count(id)".

In "layman" words, what you're telling Access to do is: Fetch me the first "categorie" value after ordering all "categorie" values from the highest to the lowest number of records stored in the table "notations".

Notice that this query does not modify anything in the underlying data, it only selects what's relevant for the task at hand.

Now, about "Step 2": Queries can take many things as data sources, including other queries. So, now that you have the most repeated "categorie", you can get all the data from the "notations" table. And, for that, we use the second query. Let's dissect it too:

select             -- Again, this is a SELECT query, so it will show rows.
    notations.*    -- Show all columns of the "notations" table.
from notations     -- You need to tell the query that you're pulling data
                   -- from the "notations" table.
     inner join    -- You will join the rows pulled from the "notations" table
                   -- with the rows of another data source, which, in this case,
                   -- is another SELECT query (it's important to remember
                   -- that if you use a SELECT statement as data source,
                   -- you need to provide an alias for it (again, use the
                   -- keyword "AS").
         (select top 1 categorie, count(id) as n
          from notations group by categorie
          order by n desc) as a
                  -- Join the data sets so the query only returns rows
                  -- where the values of "categorie" from each one is identical.
         on notations.categorie = a.categorie

In "layman" terms, what you're telling Access is: Fetch me all the values in table "notations" for which the value of "categorie" matches the value returned by the subquery provided (which was explained in "Step 1").

Again, you're not performing modifications to your data: you're just filtering in a way that is useful for whatever task you need to do.

You can use this query as a row source for another "SELECT" query, or for a Form, or for a Report; you can use it in your VBA code to perform some specific tasks. Whatever follows, it is for you to do.

Again, I suggest you get a good book on Access or SQL. I, for myself, learned some years ago from a book called "Running Microsoft Access 97" by Jon Viescas (DISCLAIMER: This is not a commercial, it's just a suggestion). Yes, it is an old book, but I can tell you from experience that Access hasn't changed much since then (yes, files can get bigger, forms are different, and there are new features... but the basics are all the same). What's important is: Find a good learning resource, do some excercises, and be creative.

Hope this helps.




回答2:


I have investigated your explanation. And this is what I came up with, of course it puts out an error, with internet searching I cannot figure out why it happens maybe you can help me.

Imports System.Data.OleDb

Public Class ViewStatistics

Public con As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & AppLocation & "\NotationsDatabase\2016\NotationsDatabase2016.accdb")
Public Dad As OleDbDataAdapter
Public Drd As OleDbDataReader
Public Cmd As OleDbCommand
Public Dst = New DataSet

Private Sub ViewStatistics_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    con.Open()

    Dim Cmd As OleDbCommand = New OleDbCommand
    Cmd.Connection = con
    Cmd.CommandText = "SELECT TOP 1 categorie, COUNT(Id) AS n FROM notations GROUP BY categorie ORDER BY n DESC"

    Cmd.ExecuteNonQuery()
    con.Close()

End Sub

End Class

As you can see I have made a Windows Form with the name ViewStatistics where I want to show the results of the Query. I know I have copied you're code example but I want to see what it does before I can fully understand what it does.

Hope this make sense to you,

Regards Jordy

PS. The exception message

An unhandled exception of type ' System.Data.OleDb.OleDbException ' occurred in system.data.dll Additional information : Values ​​for one or more required parameters are missing.




回答3:


I hope some one can push me in the right direction.

@ Barranka I found out why the above code example did not work for me.

These Lines:

select top 1 categorie, count(id) as n
from notations
group by categorie
order by n desc

Need to be:

select top 1 categorie, count(id) as n
from notations
group by categorie
order by count(id) desc

Same goes for:

select notations.*
from notations
     inner join (select top 1 categorie, count(id) as n 
                 from notations 
                 group by categorie 
                 order by n desc) as a on notations.categorie = a.categorie

Need To be:

select notations.*
    from notations
         inner join (select top 1 categorie, count(id) as n 
                     from notations 
                     group by categorie 
                     order by count(id) desc) as a on notations.categorie = a.categorie

So after a long study I have made a form and figured out on how to show the query data in my datagridview1, I made it like this (as a Private sub)

Private Sub FilterNotations(ByVal Top As String)
        Dim TopCat As String

        TopCat = "TOP " & Top


        con.Open()
        Cmd = New OleDbCommand("SELECT " & TopCat & " categorie, COUNT(Id) AS n FROM notations GROUP BY categorie ORDER BY COUNT(Id) DESC", con)
        Cmd.ExecuteNonQuery()
        con.Close()


        Using Cmd = New OleDbCommand("SELECT notations.* FROM notations INNER JOIN (SELECT " & TopCat & " categorie, COUNT(Id) AS n FROM notations GROUP BY categorie ORDER BY COUNT(Id) DESC) AS a ON notations.categorie = a.categorie", con)
            con.Open()
            Using Dad = New OleDbDataAdapter(Cmd)
                Dst.Clear()
                DataGridView1.DataSource = Dst.Tables()
                Dad.Fill(Dst, "notations")
                DataGridView1.DataSource = Dst.Tables(0)
            End Using
        End Using
        con.Close()
    End Sub

The next thing I need some help with is how can I, in addition to how I filter already use the date as in (01-07-16) to get the most occurring between date1 and date2. If some one could give me a gentle push in the right direction that would be kind.

Kind regards,

Jordy Kleian



来源:https://stackoverflow.com/questions/38129734/visual-basic-filter-on-most-occuring-in-acces-databse

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!