How to create a view? - mysql

I'm pretty new in App Maker. I want to create an app that will collect various types of request (failures, new ideas, orders and so on ). For each type of request will be separate data model. Every data model (request) contains 3 the same information: date, applicient, comments.
In addition to the dashboard's stand for each type of request, I want to make one in which all entries will be displayed with only repating records and type of request as one more record (date, applicient, comments, type of request)
I think that Calculated Model is the answer here, but despite getting acquainted with the documentation, I don't know how to implement this in my case. Could anybody halp me with this ?
Below I am presenting the display of the above description. Records 1, 2, 3 ... presents records that don't replicate in another data model.
IMAGE:
https://drive.google.com/file/d/1gi6ylZacOVSkcqtpaupRpIOrzbq7fOsT/view?usp=sharing
I tried to do relations, but I couldn't displey this in one table, what is my goal. How to conigure the SQL datasource to do this ?

You can create a new calculated SQL model with UNION:
(SELECT 'Failures' AS REQUEST_TYPE, C.* FROM Failures AS C)
UNION ALL
(SELECT 'New Ideas', C.* FROM `New ideas` AS C)
UNION ALL
(SELECT 'Orders', C.* FROM Orders AS C);
You must have corresponding fields in your datasource that match the sql column names: REQUEST_TYPE, Date, Applicient, Comments
Reference:
Cloud sql model

Related

multi-tenancy Join or multiple Select queries postgres

I am implementing multi tenancy using single database and separating data for each tenant using a tenant_id. This id is passed in the jwt token as well. I have two tables right now genre and books. genre table has columns like
tenant_id, genre_id, ..... and books table has columns genre_id, book_id, book_name, ....
So 1 genre can have multiple books associated with it and 1 tenant can have multiple genres associated with it.
Now every time a book is fetched or updated I want to make sure the right person is making these calls.
I know of two ways to do it.
First way:
Make two queries. First fetch the book, get the associated genre_id in the object. Then fetch that genre and compare the jwt tenant_id with the tenant_id inside this genre object.
Something like this
const book= await ReadBook(req.query.book_id); // fetches my book from db
const genre = await ReadBook(book.genre_id); // fetches the genre from db
if (genre.tenant_id === jwtToken.tenant_id) {..} // compare if same or not
Second way:
Do this query in db
select b.*, g.tenant_id as tenant_id
from book_data b, genre_data g
where b.book_id = '0eokdpz0l' and g.tenant_id = 'M1MzgzMDM' and b.genre_id = g.genre_id
Which method is more efficient?
If theres a more efficient method then these then please let me know too
It's good practice to stick to ORM abstraction if possible, while minimising how much and how often data is transferred to/from db. Sequelize is able to construct an equivalent to that query for you, with the necessary joins and filters on the ids. Something among the lines of:
Books.findAll({
where: {book_id: '0eokdpz0l'},
include: [{
model: Genre,
where: {tenant_id : jwtToken.tenant_id}
}]
}).then(books => {
/* ... */
});
Running multiple queries in sequence not only adds latency due to additional round trips to/from db (and possibly connection setup if you're not pooling or holding them open) but it's also moving more bytes of data around, needlessly. tenant_id mismatch on db would send back a shorter message with an empty result. Checking it on client side requires downloading data even when you'll have to discard it.

Is it a good practice to store SQL query in the database?

My Usecase:
We allow the users of the system to create a list(i.e segment) of contact details based on the variety of the filters from the UI. So they create the segment using a form to select say all people living in a particular state.
So the issue here is that, when the new contacts are added, I want these segments to be updated as well. The solution that I can think of is saving SQL query for each segment and update each segment when new contacts are added using these SQL queries.
I thought of saving only parameters in a json string format but complication in that case is filters available are over multiple tables and there is no way to generate the dynamic SQL query as it involves joins and different filters (i.e. 'in', 'endswith', etc).
I don't think either of them is the best solution. Any better ideas?
Any help would be appreciated, thanks in advance!
Update: JSON parameter and Query I need
{'is_buyer': ['1'], 'is_executive_member': ['1'], 'is_member': ['1'], 'survey_participant': ['1'], 'cluster': ['A'], 'state': ['state1'], 'city': ['ab', 'cd'], 'gender': ['male']}
Expected query output:
SELECT * FROM `contacts` INNER JOIN `contacts_clusters` ON (`contacts`.`KEY` = `contacts_clusters`.`KEY`) WHERE (`contacts`.`IS_BUYER` IN (1) AND `contacts`.`IS_EXECUTIVE_MEMBER` IN (1) AND `contacts`.`IS_MEMBER` IN (1) AND `contacts`.`SURVEY_ID` IS NOT NULL AND `contacts_clusters`.`CLUSTER` IN ('A') AND `contacts`.`STATE` IN ('state1') AND `contacts`.`CITY` IN ('ab', 'cd') AND `contacts`.`GENDER` IN ('male'))
This is just one of the example of segment filter. There are much more parameters and tables which can used for the creation of segment.
I think you'd be better off storing the required parameters for the segment, then when new contacts are added, you'd check if the new contacts match according to the stored segment parameters. If they do, then you'd update the segment.

Joining 2 tables together and using the where function based on a separate mysql query

I am building a training platform for work. I have created the requirements for a user to be trained based on a role given to them. If that role is aligned to a document it will sit against the user. I have managed to get most of the way but am struglling on the best way to finish the where statement within mysqli.
tbldocfiles is a list of my files. I am looking at docid (could be multiple files associated to the document)
tbltrainingaccess sets the roles (driver, warehouseman, customer services) and shows which role (by id) is associated to the document in docfiles.
tblusertraining is the list of users and what role they have associated to them. (driver, warehouseman, customer services).
I am listing the documents associated to the user so have thought the following is the best way:
Look at the user and how many roles he/she is allocated
Look at the roles returned in point 1 (where function)
Identify and match the documents that have the same roles as the user (Join function)
create the list, then look at the unique values for docid. (distinct value)
Example User Bri has the driver and warehouseman role.
There are 5 documents in the db, 3 of them are associated to the driver role (docid 1,2,3) and 2 of them are associated to the warehouseman role (docid 2,4) the 5th document is associayted to customerservice.
My query should do this:
List all documents associated to the roles, that are associated to the user Bri
1
2
3
2
4
Now select unique values (using docid) from the above list:
1,2,3,4.
So my answer will be a used as a count function at the end using mysql_fetch_rows
SELECT DISTINCT tbldocfiles.docid FROM tbldocfiles LEFT JOIN tbltrainingaccess ON (tbldocfiles.docid = tbltrainingaccess.docid) where groupid='1' or groupid='9'
The above code works. but i've got myself confused.
The where statement needs to be the result of a query similar to :
select * from tblusertrainingrole where userid='1' (1 will be a variable based on page selection)
the result in this would be 1, 9 which are the groupid results.
Basically any help would be appreciated! I am sure it will be simple but have burnt myself out on this for a while and most answers in here helped with joining but not the where statement (that I could find)
Thank you in advance everyone!
You can do a select statement in the where. Since it is an or statement you can use in for the results. Please replace * with the column name for the value you need. Should look like
where groupid in (select * from tblusertrainingrole where userid = '1')

correctly fetch nested list in SQL

I have a design problem with SQL request:
I need to return data looking like:
listChannels:
-idChannel
name
listItems:
-data
-data
-idChannel
name
listItems:
-data
-data
The solution I have now is to send a first request:
*"SELECT * FROM Channel WHERE idUser = ..."*
and then in the loop fetching the result, I send for each raw another request to feel the nested list:
"SELECT data FROM Item WHERE idChannel = ..."
It's going to kill the app and obviously not the way to go.
I know how to use the join keyword, but it's not exactly what I want as it would return a row for each data of each listChannels with all the information of the channels.
How to solve this common problem in a clean and efficient way ?
The "SQL" way of doing this produces of table with columns idchannel, channelname, and the columns for item.
select c.idchannel, c.channelname, i.data
from channel c join
item i
on c.idchannel = i.idchannel
order by c.idchannel, i.item;
Remember that a SQL query returns a result set in the form of a table. That means that all the rows have the same columns. If you want a list of columns, then you can do an aggregation and put the items in a list:
select c.idchannel, c.channelname, group_concat(i.data) as items
from channel c join
item i
on c.idchannel = i.idchannel
group by c.idchannel, c.channelname;
The above uses MySQL syntax, but most databases support similar functionality.
SQL is made for accessing two-dimensional data tables. (There are more possibilities, but they are very complex and maybe not standardized)
So the best way to solve your problem is to use multiple requests. Please also consider using transactions, if possible.

Querying many to many relationship with LinqToSQL

I have a database setup as follows (unfortunatelly was not allowed to publish diagram image in here so need to describe:
Responses table - contain RespondentID, QuestionID, ResponseOptionID
ResponseProperties - contain ResponsePropertyID, ResponsePropertyTypeID, Name
ResponsePropertyTypes - contain ResponsePropertyTypeID, Name
ResponsesInProperties (a many to many table) - contains ResponseID, ResponsePropertyID
There is a many to many relationship on ResponsesInProperties table. This table does not show in EF of course.
Say I have two response property types "Country" and "Wave" and corresponding ResponeProperties "USA", "UK" and "Wave2011", "Wave2012".
Now I need to get back from the database all (and not duplicated) responses that would be in USA and also in Wave2012. The trick is that every response I need must be in both Wave2012 and USA. I am trying to achieve this with LINQ to SQL. The below is Linq I came up with that get's me the correct records but they appear many times for different properties. Limiting the properties gives me no records whatsoever....
Any help appreciated!
var responses = from r in db.Responses
from rp in r.ResponseProperties
select new
{
RespondentID = r.RespondentID,
QuestionCode = r.Question.Code,
ResponseOptionCode = r.ResponseOption.Code,
ResponseOptionCodeName = r.ResponseOption.Text,
ResponsePropertyName = rp.Name,
ResponsePropertyTypeName = rp.ResponsePropertyType.Name
};
To clarify, you are trying to do this with LINQ to SQL and not EF as they have rather different models for M-M. With LINQ to SQL, you do have to include the middle join table.
The key thing missing from your query at this point is the filter (Where) clauses. You need to specify them for both sides of the join to properly filter the results. You indicate that when you supply a filter you get back no records. Can you clarify your question with that filter as it may help to fix your underlying problem.
Your query cannot produce unique responses because you also get ResponsePropertyName and ResponsePropertyTypeName, which will duplicate the results.
This entity framework query -
from r in db.Responses
where r.ResponseProperties.Any (rp => rp.Name == "USA")
where r.ResponseProperties.Any (rp => rp.Name == "Wave2012")
select new
{
RespondentID = r.RespondentID,
QuestionCode = r.Question.Code,
ResponseOptionCode = r.ResponseOption.Code,
ResponseOptionCodeName = r.ResponseOption.Text,
};
does produce unique Responses that are in USA and in Wave2012. The produced sql will show two EXISTS predicates with AND.