Using "array_agg" in a "having clause" with Sequelize

I am facing a particular scenario with my database setup. I have three tables named computers, flags, and computerFlags that establish relationships between them. The structure of the computerFlags table is as follows:

computerName | flagId
  computer1  | flag1
  computer1  | flag2
  computer2  | flag2
  computer2  | flag3

The computer3 entry does not have any flags associated with it, therefore it is not listed in the table. Using Sequelize, I am trying to create a query that will count all computers without the "flag3". In the example table above, the desired output would be 2 (for "computer1" and "computer3").

This is the current code snippet I have:

import { DataTypes, Sequelize, Op } from "sequelize";

(async () => {
    try {
        const postgresDB = new Sequelize('postgres://<my-pg-credentials>>', {
            logging: true,
        });

        const computers = postgresDB.define('computer', {
            name: {
                type: DataTypes.TEXT,
                primaryKey: true
            },
            // Other computer fields
        });

        const flags = postgresDB.define('flag', {
            id: {
                type: DataTypes.TEXT,
                primaryKey: true
            },
            name: DataTypes.TEXT,
        });
        const computerFlags = postgresDB.define('computerFlag', {}, { createdAt: false, updatedAt: false })

        computers.belongsToMany(flags, { through: computerFlags });
        flags.belongsToMany(computers, { through: computerFlags });
        await postgresDB.sync({ alter: true })
        const c = await computers.count({


            distinct: true,
            group: ['computer.name'],
            include: [

                {
                    model: flags

                },
            ]
        });
        } catch (err) { console.log(err) }
})();

When using the following SQL query, I get a partially correct result:

select count("computerName") from "computerFlags"
group by "computerName"
having '2' != all(array_agg("flagId"))

However, I am unable to replicate this behavior in Sequelize. Also, based on the table provided, the mentioned query would return 1 as 'computer3' is absent from the list.

To execute this functionality using Sequelize, I would ideally like to implement something similar to the following:

having: {
  [[Sequelize.fn('array_agg', Sequelize.col('flag.id')), 'flagIds']] : {
    [Op.all]: {
      [Op.ne]: '2'
    }
  }
}

There are two main issues with this approach:

  1. I am unable to use [[Sequelize.fn ...]] as the left operand
  2. The referencing of the flag ID might be incorrect, since it should resemble something like computer->flags->flagId. When utilizing findAll, computer->flags returns an array of flags where each contains flagId.

I am currently quite perplexed and would greatly appreciate any guidance you can offer.

Answer №1

I'm looking to run a query that will calculate the total number of computers that do not have "flag3".

To achieve this, you can utilize NOT EXISTS. (Some might refer to it as a "semi-anti-join".)

SELECT count(*)
FROM   computers c
WHERE  NOT EXISTS (
   SELECT FROM computerFlags cf
   WHERE  cf.computerName = c.computerName
   AND    cf.flagId = 'flag3'
   );

This method only excludes computers from the count if they have an entry with 'flag3'.

It is considered to be more efficient in terms of performance.

On a side note: using CaMeL case names may not be optimal for Postgres. For more information, refer to:

  • Are PostgreSQL column names case-sensitive?

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

What is the best way to input a dynamic post array in PHP?

Explaining this might be challenging, but I will do my best. I have multiple input posts with custom conditions, which means there can be as many custom conditions as needed. Here is the HTML: <input name="type[]" value="type 1"> <input nam ...

The key to successful filtering in Next.js with Hasura is timing - it's always a step

I am fetching data from Hasura using useRecipe_Filter and passing the searchFilter state as a variable. It seems that every time I press a key, the UI updates with one keystroke delay before filtered data is passed to the results state. const SearchBar = ( ...

Mastering the art of switching between different application statuses in ReactJS

As a newcomer to reactJS, I am exploring ways to make one of my components cycle through various CRUD states (creating object, listing objects, updating objects, deleting objects). Each state will correspond to displaying the appropriate form... I have co ...

Using jQuery to target a specific item from a retrieved list of elements

I'm currently working on a photo gallery feature that is reminiscent of Instagram or Facebook user photos. My goal is to enable users to view details about each image (such as the date) in a box that appears over the image when they hover over it. E ...

Is there a way to hide a paragraph or div using javascript?

I am experimenting with using buttons to hide paragraphs using javascript, but even when I set them as "hidden", there is still excess blank space left behind. Is there a way I can eliminate that extra space? Below is the javascript code: function backgro ...

Need help with resetting a value in an array when a button is clicked?

Using Tabulator to create a table, where clicking on a cell pushes the cell values to an array with initial value of '0'. The goal is to add a reset button that sets the values back to '0' when clicked. component.ts names = [{name: f ...

Storing multiple values of dynamically added elements in a single variable and accessing them within a function

Is it possible to store multiple values into a single variable and then access them in a setTimeout function? $(document).ready(function (){ div ({'div':'#noo','auto':'true','pos':'top',' ...

Nextjs optimizing page caching to reduce unnecessary rendering

Within my Next.js application, I have implemented two unique pages. Each page is designed to display a randomly selected person's name when the component is initially loaded. simpsons.tsx export default function Simpsons() { const [person, setPerso ...

Adding an iframe with inline script to my Next.js website: A step-by-step guide

For my Next.js project, I have this iframe that needs to be integrated: <iframe class="plot" aria-label="Map" id="datawrapper-chart-${id}" src="https://datawrapper.dwcdn.net/${id}/1/" style="width: ...

Assessing the string to define the structure of the object

Currently, I am attempting to convert a list of strings into a literal object in Javascript. I initially tried using eval, but unfortunately it did not work for me - or perhaps I implemented it incorrectly. Here is my example list: var listOfTempData = [ ...

Allow the response to be returned in the parent function by using the $.post method

I have a question regarding this particular code snippet: null. Why is the server_request function not returning the responseText as expected? And how can I modify it to achieve the desired outcome?

...

Create a customized menu with jQuery that disappears when hovered over

Check out this menu I've created: http://jsbin.com/useqa4/3 The hover effect seems to be working fine, but I'm looking to hide the div #submenuSolutions when the user's cursor is not on the "Solution" item or the submenu. Is there a way to ...

Tips for retrieving modified data from a smart table in Angular 4

Currently, I am working on an angular project where I am utilizing smart table. Here is a snippet of my .html file: <ng2-smart-table [settings]="settings" [source]="source" (editConfirm)="onSaveConfirm($event)" (deleteConfirm)="onDeleteConfirm($event ...

Python and JavaScript fundamental interaction

My current setup involves having a local HTML page named leaflet.html, which is being shown in an embedded browser within a python-tkinter application. Within the leaflet.html file, there exists a straightforward JavaScript code snippet that includes a fu ...

Dropping anchor whilst skipping or jumping

One of my website elements is a drop anchor that connects from a downwards arrow situated at the bottom of a full-page parallax image to another section on the same page. The HTML code snippet for the drop anchor is as follows: <section id="first" cla ...

Error message: "Unexpected token" encountered while using the three.js GLTFLoader() function

I have a requirement to load a .glb model into three.js by using the GLTFLoader. I was able to successfully create a rotating 3D mesh on a canvas without encountering any errors in the console. However, when I tried to replace it with the .glb model, I enc ...

Change the color of the background in the Material UI Snackbar

Whenever I try to change the background color of the Snackbar by setting a className, it doesn't get applied properly. Instead, for a brief moment when the page renders, the desired background color appears and then quickly gets replaced. I've g ...

Guide to transforming a TaskOption into a TaskEither with fp-ts

I have a method that can locate an item in the database and retrieve a TaskOption: find: (key: SchemaInfo) => TO.TaskOption<Schema> and another method to store it: register: (schema: Schema) => TE.TaskEither<Error, void> Within my regis ...

Disable body scrolling on mobile devices in native browsers

When using the native browser on Samsung Galaxy S5 / S6, the following CSS code: body { overflow: hidden; } does not successfully prevent the body from scrolling. Is there a way to work around this issue? Edit: As mentioned below, one workaround is t ...

Associate information with HTML elements

I've come across this question multiple times, but the solutions are mostly focused on HTML5. My DOCTYPE declaration is: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> I'm looking t ...