Sequelize: how to do nested subquery in one to many field? - javascript

I have two tables; one is "user" another is "post". User has a one-to-many relationship with "post". "post" has a foreign key field named user_id.
user table:
+----+--------------------------------------+--------+------------+-----------+------------------+----------+------+---------------------+---------------------+
| id | uuid | name | first_name | last_name | email | password | role | createdAt | updatedAt |
+----+--------------------------------------+--------+------------+-----------+------------------+----------+------+---------------------+---------------------+
| 1 | 37b4e543-ae46-45ef-a216-dea4ee79d6f7 | riyad | 0 | 1 | riyad#gmail.com | 123456 | 1 | 2021-11-22 17:56:56 | 2021-11-22 17:56:56 |
| 2 | d63c3414-db52-4784-9de8-b99a6659f1c9 | riyad2 | 6 | 7 | riyad2#gmail.com | 123456 | 5 | 2021-11-22 20:01:36 | 2021-11-22 20:01:36 |
+----+--------------------------------------+--------+------------+-----------+------------------+----------+------+---------------------+---------------------+
post table:
+----+---------+--------+---------+--------------------------------------+---------------------+---------------------+
| id | title | body | user_id | slug | createdAt | updatedAt |
+----+---------+--------+---------+--------------------------------------+---------------------+---------------------+
| 1 | title 1 | body 1 | 1 | 6e95b4a2-f101-48cd-8fea-8b53850c54b0 | 2021-11-22 17:57:56 | 2021-11-22 17:57:56 |
| 2 | title 2 | body 2 | 1 | 47d0cdbe-af3b-446a-badf-5197d8796133 | 2021-11-22 17:58:02 | 2021-11-22 17:58:02 |
| 3 | title 3 | body 3 | 2 | 347e200b-bffd-423d-b481-48d1b74ecc75 | 2021-11-22 20:02:04 | 2021-11-22 20:02:04 |
+----+---------+--------+---------+--------------------------------------+---------------------+---------------------+
Now I want to get the users who posted from 2021-11-22 15:00:00 to 2021-11-22 20:00:00.
In this case the first two posts (post id 1 and 2) were made in this time which were posted by user_id 1. Now I want to get that user(s) details in single query.
This is the SQL query I would do like use:
select *
from user
where id = any(select user_id from post
where createdAt >= "2021-11-22 15:00:00"
and created_at <= "2021-11-22 20:00:00")
Now how can I write that in sequelize?

You want this Sequelize doc page.
Long story short (at least in my opinion), sub queries will be hard to handle in any ORM. I would advise to use raw SQL instead.

Related

Dexiejs - Filtering returns single value

My dexiedb structure looks like below.
const db = new Dexie('shipment-execution');
db.version(1).stores({
root: '++id,shipmentid,stopid',
})
My IndexedDB will look like below
| id| shipmentid| stopid|
| 1 | 6000001 | 10 |
| 2 | 6000001 | 20 |
| 3 | 6000001 | 30 |
| 4 | 6000002 | 10 |
| 5 | 6000002 | 20 |
I am trying to get all the data which has shipmentid equal to 6000001. Each time it is returning only one record (the first record ).
db.root.where({shipmentid : '6000001'}).toArray().then((d)=>{
console.log(d);
})
output is only fetching the first record
| id| shipmentid| stopid|
| 1| 6000001 | 10 |
Please let me know, what I am doing wrong.

how to use a where clause to see if an id exists in a postgres array type column

What I'm trying to do is, join an "events" table on two other tables: "users" and "locations".
Every "event" happens at a specific time and on a specific "location" which needs joining in order for the user to know where the event will take place. And is also created by a specific "user". this user happens to have an array of user ids called close_friends. The three tables are the following:
Events table
===================================================
Column | Type |
-----------------------+--------------------------+
id | integer |
location_id | integer |
guests | integer |
hide_from | integer[] |
only_close_friends | boolean |
is_public | boolean |
min_viable_population | integer |
max_viable_population | integer |
created_by | integer |
sport_type | text |
whats_needed | text[] |
happens_at | timestamp with time zone |
created_at | timestamp with time zone |
updated_at | timestamp with time zone |
updated_by | integer |
___________________________________________________
Users table
===========================================
Column | Type |
---------------+--------------------------+
id | integer |
username | text |
password_hash | text |
first_name | text |
last_name | text |
gender | text |
photo | text |
city | text |
bio | text |
height | integer |
sports | text[] |
photos | text[] |
friends | integer[] |
close_friends | integer[] |
scopes | text[] |
verified | boolean |
created_at | timestamp with time zone |
updated_at | timestamp with time zone |
updated_by | integer |
___________________________________________
Locations table
==========================================
Column | Type |
---------------+--------------------------+
id | integer |
name | text |
maps_url | text |
city | text |
region | text |
cost | text |
photo | text |
meta | text |
sport_types | text[] |
girls_allowed | boolean |
verified | boolean |
created_at | timestamp with time zone |
created_by | integer |
updated_at | timestamp with time zone |
updated_by | integer |
Now The user should be able to create an event which is visible only to his/her close friends.
what I wanna do is fetch only the events that are to be seen by creator's close friends. To give you an overall idea of what I'm trying to achieve, I'd provide you with the code block that looks good but returns an "Operator doesn't exist" error.
const query = db('events')
.join('users', 'users.id', '=', 'events.created_by')
.join('locations', 'locations.id', '=', 'events.location_id')
.select(
'events.id',
'events.location_id',
'locations.name',
'events.guests',
'locations.city',
'events.min_viable_population',
'events.max_viable_population',
'events.created_by',
'events.sport_type',
'events.whats_needed',
'events.happens_at',
'events.created_at',
'users.username',
'users.first_name',
'users.last_name',
'users.photo',
'users.verified'
)
.where({'only_close_friends': true})
.whereIn('close_friends', function () { /////////////////////////
this.select('id') /////////////////////////
.from('users') // The problem is here //
.where({ id: user_id }) /////////////////////////
}) /////////////////////////
Note
"user_id" is the id of the correctly logged in user.
I was able to find a simple solution with the help of a friend:
.whereRaw('? = ANY(users.close_friends)',[user_id])

Get the sibling value of a SQLITE value

I have a SQLite Table:
+---------+-----------+-----------+-----------+
| userID | balance | ledger | lasttopup |
+---------+-----------+-----------+-----------+
| 1 | 90 | 780 | 12/10/18 |
| 2 | 180 | 0 | 4/11/18 |
| 3 | 270 | 12 | 13/10/18 |
| 4 | 360 | 109 | 11/10/18 |
+---------+-----------+-----------+-----------+
And I am accessing the column ledger via:
const conn = new require('better-sqlite3')('../../data/databases/casino.sqlite3');
const balances = conn.prepare(`SELECT * FROM "${msg.guild.id}"`).all().map(e => e.ledger)
And I want to get the userID which pertains to the respective ledger entry.
Visual:
Visualization
And then perform an action on the ledger value.
But I am unsure of how to retrieve the userID.
Any help will we appreciated!
[LIBRARIES]
DiscordJS
better-sqlite3
~Thanks

Running same query with different where clause for showing in different tabs on page

I have a list of companies like this
+-------+---------+------+---------------+
| Title | Address | City | CompanyTypeId |
+-------+---------+------+---------------+
| A | Address | City | 1 |
| B | Address | City | 2 |
| C | Address | City | 2 |
| D | Address | City | 3 |
| E | Address | City | 2 |
| F | Address | City | 2 |
| G | Address | City | 4 |
| H | Address | City | 5 |
| I | Address | City | 2 |
| J | Address | City | 6 |
| K | Address | City | 7 |
| L | Address | City | 2 |
+-------+---------+------+---------------+
I am tasked with seperating them according to their types and list them under seperate tabs on our page.
So basically I need to show a list of same query with changing where conditions.
I set the bootstrap tabs and was wondering if it was possible parameterize the variable and change it with tab changes on page. I guess I'll have to use AJAX but not sure if it's the right choice either.
And of course, if it's possible how can I do it?

How to parse data from a mysql tracking db?

I have a working event tracker that writes every event in a mysql table.
Table
id date userid event
5100 2014-03-25 14:18:55 user333 AI
5101 2014-03-25 14:19:02 user333 Click
5102 2014-03-25 14:19:02 user333 Click
...
Thats works so far very good. But now, I want to write a little report tool in node.js
I try to get the values with this SQL Query:
SELECT DATE_FORMAT(date,"%Y%m%d") AS date, event, count(*) AS count FROM databasetest WHERE date>="'+ daystartdate +'" AND date<="'+ dayenddate +'" GROUP BY YEAR(date), MONTH(date), DAY(date), event
Giving me this:
+----------+----------+-------+
| date | event | count |
+----------+----------+-------+
| 20140320 | AI | 6 |
| 20140320 | Click | 2 |
| 20140320 | swipe | 2 |
| 20140321 | Click | 6 |
| 20140321 | error | 5 |
| 20140321 | swipe | 2 |
| 20140321 | touch | 3 |
| 20140322 | AI | 3 |
| 20140322 | Click | 3 |
| 20140322 | error | 1 |
| 20140322 | mapsload | 3 |
| 20140322 | touch | 1 |
| 20140323 | AI | 2 |
| 20140323 | Click | 2 |
| 20140323 | touch | 5 |
| 20140324 | AI | 3 |
| 20140324 | Click | 1 |
| 20140325 | AI | 25 |
| 20140325 | Click | 48 |
| 20140325 | error | 16 |
| 20140325 | mapsload | 7 |
| 20140325 | swipe | 15 |
| 20140325 | touch | 32 |
+----------+----------+-------+
But I need the data in this form:
+----------+----------+-------+-----
| date | Click | AI | ....
+----------+----------+-------+-----
| 20140320 | 0 | 6 |
| 20140321 | 2 | 2 |
| 20140321 | 2 | 5 |
Is this possible with a SQL query or do I need to loop through the results in my javascript code. I tried many possible solution but didnt get it to work.
Thank you.
This is a very common question, keywords to search are "transpose" and "pivot". To save you the trouble, this is something that MySQL is not able to do. SQL Server (a MS product) can do this, though.
You will need to loop through the output and build the result set yourself.
var results = []
data.forEach(function(row, rowidx) {
results[row.date] = results[row.date] || {};
results[row.date][row.event] = results[row.date][row.event] || 0;
results[row.date][row.event] += row.count;
});

Categories

Resources