Creating a personalized aggregation function in a MySQL query

Presenting the data in tabular format:

id | module_id | rating

1  |        421   | 3          
2  |        421   | 5        
3. |        5321  | 4          
4  |        5321  | 5           
5  |        5321  | 4              
6  |        641   | 2   
7  |        641   | 3           
8  |        641   | 3            
9  |        641   | 2          
10 |        7201  | 4          
11 |        7201  | 4               
12 |        7201  | 3    

My code involves fetching ratings of a module id and sorting them using a custom formula, followed by arranging module ids in descending order based on the formula value.

Below is the code snippet:

let arr = [421,5321,641,7201];
let temp = [], ci_bounds = [];
for(let j=0; j<arr.length; j++){
    // Code logic for fetching and calculating lower bounds
}

The 'temp' array contains sub-arrays with module_id as the first element and corresponding lower bound as the second element.

temp value for above data
[
    [
        421,
        0.09452865480086611
    ],
    [
        5321,
        0.43849391955098216
    ],
    [
        641,
        2.8316237110415135e-17
    ],
    [
        7201,
        0.20765495512648788
    ]
]

The 'arr' array is then sorted based on these lower bounds to get the final reordered result. Here's how the sorting is done:

// Sorting logic

Final answer after sorting: [5321, 7201, 421, 641]

Is there a way to perform this aggregation directly in a query?

Answer №1

To calculate the values for pos and neg for each module_id, you can use a subquery in combination with an outer query to determine the lower_bound:

SELECT
    module_id,
    ((pos + 1.9208) / (pos + neg) - 1.96 * SQRT((pos * neg) / (pos + neg) + 0.9604) / (pos + neg)) / (1 + 3.8416 / (pos + neg)) as lower_bound
FROM (
    SELECT module_id, SUM(rating > 3) AS pos, SUM(rating <= 3) AS neg
    FROM ratings
    GROUP BY module_id
) posneg
ORDER BY lower_bound DESC;

The resulting output includes:

+-----------+------------------------+
| module_id | lower_bound            |
+-----------+------------------------+
|      5321 |    0.43849391932274523 |
|      7201 |    0.20765495508553936 |
|       421 |    0.09452865480086611 |
|       641 | 2.8316237110415135e-17 |
+-----------+------------------------+

If only the module_id values are required, adjust the calculation of lower_bound within the ORDER BY clause:

SELECT
    module_id
FROM (
    SELECT module_id, SUM(rating > 3) AS pos, SUM(rating <= 3) AS neg
    FROM ratings
    GROUP BY module_id
) posneg
ORDER BY
    ((pos + 1.9208) / (pos + neg) - 1.96 * SQRT((pos * neg) / (pos + neg) + 0.9604) / (pos + neg)) / (1 + 3.8416 / (pos + neg))
    DESC;

This modified query yields:

+-----------+
| module_id |
+-----------+
|      5321 |
|      7201 |
|       421 |
|       641 |
+-----------+

To specify specific module_id values, you can inject them using JavaScript into the SQL query. Be sure to adjust the SQL query accordingly. For example, including values like 5321, 421, 641, 7201, and 26 (which is not in the ratings table and receives a zero lower_bound):

SELECT
    module_id
FROM (
    SELECT t.column_0 as module_id, SUM(rating > 3) AS pos, SUM(rating <= 3) AS neg
    FROM (VALUES
        ROW(421),
        ROW(5321),
        ROW(641),
        ROW(7201),
        ROW(26)
    ) t
    LEFT JOIN ratings ON t.column_0 = ratings.module_id
    GROUP BY t.column_0
) posneg
ORDER BY
    ((pos + 1.9208) / (pos + neg) - 1.96 * SQRT((pos * neg) / (pos + neg) + 0.9604) / (pos + neg)) / (1 + 3.8416 / (pos + neg))
    DESC;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Problems with the Chosen property of MenuItem within Material-UI

The MenuItem's "selected" property does not seem to be functioning correctly within the Select component. For reference, please visit https://codesandbox.io/s/9j8z661lny I have attempted to use comparison with the Id, and even tried using selected={t ...

Respond to a recommendation with a response

I've been working on setting up a bot for my Discord server, and I recently added a "marry" command to it. Whenever a user makes an offer, a message announcing the proposal pops up with two reaction options. The first reaction signifies yes, while th ...

Customizing ESLint configurations for a more productive local development environment

Let's consider an inspiring scenario: I am in the process of coding and need to troubleshoot an issue, so here is a snippet of my code: function foo() { console.log("I'm resorting to printf debugging in 2016"); } However, our build setup in ...

Utilize jQuery and AJAX to refresh functions after each AJAX call for newly added items exclusively

I have encountered an issue with my jQuery plugins on my website. Everything functions smoothly until I load new elements via AJAX call. Re-initializing all the plugins then causes chaos because some are initialized multiple times. Is there a way to only i ...

Attempting to modify the information within the #content division of a webpage through the activation of a linked image within a jquery slideshow

I'm completely stuck on this one, even though I'm relatively new to jquery. My goal is to design a webpage where there is a slideshow of products at the top, and when a user clicks on one of the products, it should update the main #content div w ...

Issue encountered while trying to download Jade through npm (npm install -g jade)

I am having trouble downloading jade via npm on my Mac (Yosemite). After downloading node and updating npm, I tried to install jade but encountered a series of errors that I cannot resolve. Even attempting to use sudo did not help, as it only displayed s ...

Is there a way to display a Google Map marker after a certain amount of time without needing to refresh the

Is it possible to update Google Map markers without refreshing the map itself every 30 seconds? The markers' latitudes and longitudes are retrieved from a database. Once obtained, these markers are then allocated onto the Google Map. However, the i ...

Discover the effective method in Angular to display a solitary password validation message while dealing with numerous ones

Here is the pattern we use to validate input fields: The length of the input field should be between 6 and 15 characters. It should contain at least one lowercase letter (a-z). It should contain at least one uppercase letter (A-Z). It should contain at le ...

Ways to merge multiple cells horizontally in a table right from the beginning

Is there a way to start the colspan from the second column (Name)? See image below for reference: https://i.stack.imgur.com/RvX92.png <table width="100%"> <thead style="background-color: lightgray;"> <tr> <td style="width ...

What is the best way to rotate a cube when it is clicked on?

My current project involves rotating a cube by clicking on buttons either on the cube itself or floating next to it. At the moment, I have them floating for easier testing purposes, but placing them directly on the cube is not an issue. The main issue I&a ...

How can I extract the value from the object returned by an AJAX call?

HTML file <div class="container"> <table id="headerTable" class="table table-bordered"> <thead> <tr> <th colspan="2">Header</th> </tr> </thead> <tbody> <c:forEach item ...

Ruby on Rails and JSON: Increment a counter with a button press

How can I update a count on my view without refreshing the page when a button is clicked? application.js $(document).on('ajax:success', '.follow-btn-show', function(e){ let data = e.detail[0]; let $el = $(this); let method = this ...

Issues with the .change(function() JavaScript in Internet Explorer versions less than 9

I'm experiencing issues with this script in Internet Explorer versions below 9. Can someone please help me identify what is wrong with my script? Thank you. IE7 and IE8 are showing the following error: SCRIPT87: Invalid argument. Found ...

Leveraging ng-click and ng-hide/show directives within ng-repeat in Angular

I have a simple Single Page Website built with Angular. I utilized ng-repeat to generate content on the main page, where each item is an image. I am looking to create an alternate view for each image to display more details. I have implemented this feature ...

In PhantomJS, where is the location of the "exports" definition?

Consider the following code snippet from fs.js: exports.write = function (path, content, modeOrOpts) { var opts = modeOrOptsToOpts(modeOrOpts); // ensure we open for writing if ( typeof opts.mode !== 'string' ) { opts.mode = ...

Safeguarding intellectual property rights

I have some legally protected data in my database and I've noticed that Google Books has a system in place to prevent copying and printing of content. For example, if you try to print a book from this link, it won't appear: How can I protect my ...

What is the method for locating all anchor tags "In General" within the inner HTML of a div using XPath?

This query is related to a discussion on anchor tags in this thread. I am interested in identifying all anchor tags within a string. The scenario provided below is similar to the aforementioned issue, however, I aim to accomplish this using xpath and angu ...

Both the maxlenght and ng-maxlength directives appear to be ineffective in AngularJS

In my HTML file, I have the following input: <input name="password" id="newPasswordConfirmation" ng-model="newPasswordConfirmation" type="number" inputmode="numeric" placeholder="" required ...

Emphasizing Text Within Div Element

Imagine having a div element structured as such: <div id="test" class="sourcecode"> "Some String" </div> Can CSS and JavaScript be utilized to highlight a specific portion of that string based on a search query? For instance, if the search q ...

Using the -t or --testNamePattern in Jest will execute all tests

Currently, I have set up my testing framework using jest and ts-jest based on the guidelines provided by the ts-jest documentation. When I execute the command yarn test --listTests, I can identify the specific test file I intend to run: processNewUser.ts ...