accessing mysql columns as arrays - mysql

i have two tables one for posts and another one for comments ,
posts table
post_id
text
1
row1
2
row2
3
row3
comments
post_id
Another header
user id
1
comment
2
1
comment 2
3
i want to read the code as follows:
post:{
id:1,
comments:[{text:"My comment",userId:3},
}

const db = require('mysql2'); // async/await works only in mysql2
// I am supposing your comments table has post_id, another_header and user_id columns
app.get('/comments', async (req, res) => {
const comments = await db.query('Select * from comments');
let arrayOfObjects = [];
comments.forEach(elem => {
arrayOfObjects.push({
id: elem.post_id,
comments: elem.another_header,
user_id: elem.user_id
});
})
console.log(arrayOfObjects);
});

Related

I try to make a Daily Gamble Game however

I try to get the Highest Number out of my Databse.
So far so good Test 1 Code:
const db = require("../../../database.js")
const test = require("./test.js")
module.exports = {
config: {
name: "try",
description: "Replies with a Number.",
},
permissions: ['SendMessages'],
owner: false,
run: async (client, message, args, prefix) => {
const test = await db.query("select Number, MemberID from numbers order by Number DESC LIMIT 3;")
console.log(test[1])
console.log(test[1].Number)
}}
But all I get out in my Console is:
Executing (default): select Number, MemberID from numbers order by Number DESC LIMIT 3;
[ { Number: 138, MemberID: '318735407963439104' } ]
undefined
So I tried another Version:
const db = require("../../../database.js")
module.exports = {
config: {
name: "stats",
description: "Replies with a Number.",
},
permissions: ['SendMessages'],
owner: false,
run: async (client, message, args, prefix) => {
const query = await db.query("select Number, MemberID from numbers order by Number DESC LIMIT 3;", async function (err, result, fields)
{
console.log(query)
const level = result[0].Number
const user = result[0].MemberID
const level1 = result[1].Number
const user1 = result[1].MemberID
const level2 = result[2].Number1
const user2 = result[2].MemberID
console.log(level)
})
}
};
But this just showed this in the Console
Executing (default): select Number,MemberID from numbers order by Number DESC LIMIT 3;
and nothing else.
I'm really depressed that nothing works, can someone help?

How to process req.body received as an array

I have a myPlaylistSongs table, and there are Playlist_ID and Song_ID columns in it.
Each row can have only one value, and the table format is as follows.
=====================
Playlist_ID | Song_ID
---------------------
1 | 5
1 | 3
1 | 8
=====================
Customers can create a playlist and add multiple songs to it, or delete multiple songs from it.
Playlist_ID is received as Path params, and Song_ID is received as req.body.
If Song_ID is received as an array here, how can I add the Song_ID corresponding to the Playlist_ID received as Path params at once?
The query is as below.
DAO.js
const postSongs = async(playlistId, songId) => {
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES(?, ?)`,
[playlistId, songId],
);
return playlist;
};
I need help.
Try something like this
const postSongs = async(playlistId, songId) => {
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES ${songId.map((sID) => "("+sID+","+playlist_id+")").join(",")},
);
return playlist;
};
You should be able to build a single query by specifying an array of (?, ?) and for the values to be inserted:
const postSongs = async (playlistId, songId) => {
if (songId.length === 0) return []; // Empty array
let valuesString = '(?, ?),'.repeat(songId.length);
// Remove last comma
valuesString = valuesString.substring(0, values.length - 1);
const valuesArr = [];
for (const song of songId) {
valuesArr.push(playlistId);
valuesArr.push(song);
}
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES ${values}`,
valuesArr
);
return playlist;
};

typeorm find row by array of ids of another table but all values in this array must be present in one relation

I'm working on a chatting app.
I have table messages_thread:
#Entity("messages_thread")
export class MessagesThreadEntity {
#PrimaryColumn({
type: 'bigint',
name: 'id',
})
id: number;
#OneToMany(type => MessagesThreadUsersEntity, a=> a.thread)
users!: MessagesThreadUsersEntity[];
constructor(init?: Partial<MessagesThreadEntity>) {
Object.assign(this, init);
}
}
And table messages_thread_users
#Entity("messages_thread_users")
export class MessagesThreadUsersEntity {
#PrimaryColumn({
type: 'bigint',
name: 'id',
})
id: number;
#Column("bigint", {
nullable: false,
name: 'user_id',
})
user_id: number;
#Column("bigint", {
nullable: false,
name: 'thread_id',
})
thread_id: number;
#ManyToOne(type => MessagesThreadEntity, a => a.users)
#JoinColumn({
name: 'thread_id',
referencedColumnName: 'id'
})
thread!: MessagesThreadEntity;
constructor(init?: Partial<MessagesThreadUsersEntity>) {
Object.assign(this, init);
}
}
I'm trying to use createQueryBuilder to do a complicated query where I need to get the thread that has users matched to the 'user_ids' array. But there is a catch, this thread should have all these users I'm looking for, no more or fewer users.
example:
I'm looking for the thread that has user_ids = [1,2,5], and I have these threads:
thread A has users [1,2,3,4,5,6]
thread B has users [2,5]
thread C has users [1,2,5]
In this case, I want thread C to be returned from the database.
NOT thread A since it has more users than [1,2,5]
NOT thread B since it does not have all the users that I want.
I need the thread that has exactly the array I'm looking for, which is thread C.
What I did so far:
let threadUsers = await this.messagesThreadUsersRepo.createQueryBuilder()
.select()
.where('affiliate_id IN (:...allUserIds)', { allUserIds })
.getMany();
NOTE: I am using NestJs, and the database is MySQL
UPDATED
To get the wanted result, you have to use the HAVING clause because we should specify a condition for filtering values using a function in MySQL used to concatenate data from multiple rows into one field (GROUP_CONCAT).
const ids= allUserIds.sort((a, b) => b - a).toString();
return await this.messagesThreadUsersRepo.createQueryBuilder()
.select(["GROUP_CONCAT(user_id ORDER BY user_id DESC) as ids ","o.*"])
// GROUP_CONCAT(user_id) here to get all the user ids by thread
.groupBy('thread_id')
.having(`ids = '${ids}'`)
// here we check if thread has the exact ids we want
.getRawMany();
FOR GLOBAL EXAMPLE WITH MYSQL QUERY using W3SCHOOL DATABASE Editor
SELECT o.*,GROUP_CONCAT(p.ProductID) as childs FROM OrderDetails as o
join Products as p on o.ProductID = p.ProductID GROUP BY o.OrderID
HAVING childs = '11';

running a query on each iteration

Can somebody help me with this query on a returned query?
I want the query to iterate through the results of the previous query to see if a voucher has been used
this is the code for the query :
db.query('SELECT * FROM Table WHERE ID in ?', [(1,2,3,4)],
function(err, rows) {
if (err) throw err
var items = []
rows.forEach(function(i) {
var item = {
'item1': i.item1,
'item2': i.item2,
'item3': i.item3
}
db.query('SELECT * FROM Table2 WHERE ID = ?', [i.ID],
function(err, rows2) {
if (err) throw err
item.subvalue = rows2
})
items.push(item)
})
res.json(items)
})
So I did this in the end. used multiple statement where the second query returns all possible results need for results in query 1. Then I can iterate through results 1 and results 2 within it.
Still not sure this is the best approach but it works. Any suggestions are very welcome
db.query('SELECT 1 WHERE Range ?; SELECT 2 WHERE ID IN (SELECT 1)',
[req.body.hotelid, '2015-11-01', '2015-11-30',
req.body.hotelid, '2015-11-01', '2015-11-30'],
function(err, result) {
if (err) console.log(err)
else
var items = []
result[0].forEach(function(i) {
var giftVoucherUsed = []
var item = {
'ID': i.BookingID,
'BookingDate': i.BookingDate,
'GuestName': 'Guestname'
}
result[1].forEach(function(g){
if(g.BookingID == i.BookingID){
giftVoucherUsed.push(g)
}
})
item['GiftVoucher'] = giftVoucherUsed
items.push(item)
})
res.json(items)
});

LINQ-to-SQL GroupBy across Many-to-Many Divide

I have the following issue to solve.
I have an IQueryable list of Invoices, each tied to an Account. Each Account can have multiple Structures, and Accounts and Structures are tied together by a table called StructureAccount. It looks like this:
Invoice ---> Account <-----StructureAccount ----> Structure
I want to query my IQueryable list of Invoices and group by Structure.StructureID or StructureAccount.StructureID. But, because any given invoice can be tied to multiple Structures the best I can get is a LIST of StructureIDs, and therefore my GroupBy is not working.
I feel like I am missing an obvious solution to this.
I should note that I understand that the data in any one Invoice would be counted multiple times if the Invoice were tied to more than one Structure, and this is "solved" by a "PercentAllocationtoStructure" value in the table StructureAccount.
I hope I did a good enough job explaining this problem. Let me know if not.
Hmmm...I might be missing something, but doesn't the following work?
var q = from i in Invoice
join a in Account
on i.AccountID equals a.AccountID
join sa in StructureAccount
on i.AccountID equals sa.AccountID
join s in Structure
on sa.StructureID equals s.StructureID
group i by s.StructureID;
I tested it on the following dummy data:
var Invoice = new [] {
new { InvoiceID = 1, AccountID = 1 },
new { InvoiceID = 2, AccountID = 2 },
new { InvoiceID = 3, AccountID = 3 },
new { InvoiceID = 4, AccountID = 1 },
new { InvoiceID = 5, AccountID = 2 },
new { InvoiceID = 6, AccountID = 3 }
};
var Account = new [] {
new { AccountID = 1 },
new { AccountID = 2 },
new { AccountID = 3 },
};
var StructureAccount = new [] {
new { AccountID = 1, StructureID = 2 },
new { AccountID = 1, StructureID = 3 },
new { AccountID = 2, StructureID = 2 },
new { AccountID = 3, StructureID = 1 },
new { AccountID = 3, StructureID = 2 },
};
var Structure = new [] {
new { StructureID = 1 },
new { StructureID = 2 },
new { StructureID = 3 }
};
And it returns:
StructureID = 2:
InvoiceID's: 1,2,3,4,5,6
StructureID = 3:
InvoiceID's: 1,4
StructureID = 1:
InvoiceID's: 3,6
I'll assume you have the following starting point:
IQueryable<Invoice> _invoices;
First, you need to get a list of all the items that you will be iterating over:
IQueryable<Account> _accounts = _invoices.Select(myInvoice => myInvoice.Account).Distinct();
IQueryable<StructuredAccount> _structuredAccounts = _accounts.SelectMany(myAccount => myAccount.StructuredAccounts);
IQueryable<Structure> _structures = _structuredAccounts.Select(myStructuredAccount => myStructuredAccount.Structure).Distinct();
Next, you need to go back and join your Structure objects to the respective Invoice objects.
For this, you'll:
Get a set of {Structure, Account} pairs:
var structureAccountJoin = _structures.Join(_structuredAccounts, _structure => structure.StructuredID, _structuredAccount => _structuredAccount.StructuredID, (structure, structuredAccount) => new { Structure = structure, Account = structuredAccount.Account });
Get a set of {Structure, Invoice} pairs:
var structureInvoiceJoin = structureAccountJoin.Join(_invoices, myObj => myObj.Account.AccountID, invoice => invoice.AccountID, (myObj, invoice) => new { Structure = myObj.Structure, Invoice = invoice});
Finally, you can group everything by the Structure object:
IQueryable<IGrouping<Structure, Invoice>> groupByStructure = structureInvoiceJoin.GroupBy(obj => obj.Structure, result => result.Invoice);
(GroupBy documentation: http://msdn.microsoft.com/en-us/library/bb534304.aspx)
Now, you can access everything as follows:
foreach(IGrouping<Structure, Invoice> groupEntry in groupByStructure)
{
Structure currentGrouping = groupEntry.Key;
foreach(Invoice inv in groupEntry)
{
// do something;
}
}
As a note, this is a very complex script that requires a lot of steps if you don't have access to the tables directly. You may want to look into creating a StoredProcedure for this instead, as it will be more efficient and you'll be able to use SQL Joins instead. If you have only an IQueryable<Invoice> to work with and access to nothing else, there is probably a design problem somewhere in your architecture.
Nevertheless, this is the way to make it work based on your requirements, if I read them correctly.