How to Join two Queries in Sequelize - sql

I tried to join two queries and based on it find the result. I am able to write the code in SQL. My SQL Code is
SELECT a.awbid,
m.mpscount
FROM ( select a.awbid
FROM awbmaster a
where a.batchid ='B/117/15022022'
and a.hubid ='117'
) as a
left join ( select count('mpsid') as "mpscount" ,
awbid from
mpsmaster m
where m.batchid = 'B/117/15022022'
group by "awbid"
) as m on a.awbid = m.awbid
But, I am not yet found any solution regarding the sequelize. How can I write the above SQL code in sequelize?

First, we can simplify this SQL query simply using a subquery to find out mpscount:
SELECT a.awbid,
(SELECT count(*)
FROM mpsmaster m
WHERE m.batchid = 'B/117/15022022'
AND m.awbid=a.awbid ) AS mpscount
FROM awbmaster a
WHERE a.batchid ='B/117/15022022'
AND a.hubid ='117'
Now if we already have both models MpsMaster and AwbMaster and a correct association between them then we can make a request something like this:
const records = AwbMaster.findAll(}
attributes: [
'awbid',
[Sequelize.literal('(SELECT count(*) FROM mpsmaster m WHERE m.batchid = \'B/117/15022022\' AND m.awbid=AwbMaster.awbid)'), 'mpscount']
]
})

Related

Update From Select with Correlated Subquery and Join in PostgreSQL

I am migrating from SQL Server to Postgres and it has gone okay for the most part. One of the issues is that I am unable to figure out how to make this query work in Postgres:
update
"Measure"
set
DefaultStrataId = StrataId
FROM (SELECT "Strata"."MeasureId",
Min("Strata"."index") AS "Index"
FROM "Strata",
"Measure"
WHERE "Strata"."MeasureId" = "Measure"."MeasureId" and "Strata"."StrataId" in (select strataid from point)
GROUP BY "Strata"."MeasureId") a
INNER JOIN strata
ON "Strata"."index" = a."index"
where "Strata"."MeasureId" = "Measure"."MeasureId";
It complains: SQL Error [42601]: ERROR: syntax error at or near "FROM"
How do I get this to work?
You can use a DISTINCT ON for this to simplify it.
The ORDER BY in the sub-query will make sure that it's the "StrataId" for the minimum "index".
UPDATE "Measure" m
SET "DefaultStrataId" = q."StrataId"
FROM
(
SELECT DISTINCT ON (s."MeasureId") s."MeasureId", s."index", s."StrataId"
FROM "Strata" s
JOIN "Point" p ON p."StrataId" = s."StrataId"
JOIN "Measure" m ON m."MeasureId" = s."MeasureId"
ORDER BY s."MeasureId", s."index"
) q
WHERE q."MeasureId" = m."MeasureId";
Test on db<>fiddle here
Btw, the query below also works with the test data in that fiddle.
Basically, in Postgresql quoting a name isn't the same as not quoting a name.
MS Sql Server is much more tolerant in that aspect.
UPDATE "Measure"
SET "DefaultStrataId" = "StrataId"
FROM (SELECT "Strata"."MeasureId",
Min("Strata"."index") AS "index"
FROM "Strata",
"Measure"
WHERE "Strata"."MeasureId" = "Measure"."MeasureId" and "Strata"."StrataId" in (select "StrataId" from "Point")
GROUP BY "Strata"."MeasureId") a
INNER JOIN "Strata"
ON "Strata"."index" = a."index"
where "Strata"."MeasureId" = "Measure"."MeasureId";
Funky. After feeling shamed by #wildplasser to make my query non-disgusting, everything magically started working. It's not like I changed anything except switching to standard joins and adding aliases:
update
"Measure" m set
"DefaultStrataId" = "StrataId"
from
(
select
s."MeasureId",
min(s."Index") as "Index"
from
"Measure" m
inner join "Strata" s on
s."MeasureId" = m."MeasureId"
where s."StrataId" in (
select
s."StrataId"
from
"Point")
group by
s."MeasureId") a
inner join "Strata" s on
s."Index" = a."Index"
where
s."MeasureId" = m."MeasureId";
Your only goal appears to be getting the minimal value from Strata
Omitting all the ugly quotes,and adding some aliasses (assuming that only one record with the minumum value exists) :
UPDATE Measure m
SET DefaultStrataId = s.StrataId
FROM Strata s
WHERE s.MeasureId = m.MeasureId
AND NOT EXISTS (
SELECT * FROM Strata nx
where nx.MeasureId = s.MeasureId
AND nx."index" < s."index"
)
;

How do I convert a set of basic (non-nested) views into a single nested query?

I have used a sequence of basic non-nested SQL View queries to slowly filter data from multiple tables to obtain a result I was after. The first query has used base relations as the input, the subsequent queries have used the base relations and/or the results from the previous query. The final query has displayed the result I was after.
First query:
CREATE VIEW ActiveRobbers
AS
SELECT a.RobberID, Nickname, NoYears, BankName, Share
FROM info.Robber a, info.Accomplices b
WHERE a.RobberID = b.RobberID;
Second query:
CREATE VIEW ActiveRobbers2
AS
SELECT Nickname, NoYears, COUNT(RobberID) AS NoRobberies, SUM(Share) AS TotalEarnings
FROM ActiveRobbers
GROUP BY Nickname, NoYears;
Final query:
CREATE VIEW ActiveRobbers3
AS
SELECT Nickname
FROM ActiveRobbers2
WHERE NoYears = 0
AND NoRobberies > (SELECT AVG(NoRobberies) FROM ActiveRobbers2);
How would I go about converting this into a single nested query using select statements? Is there some sort of rule you can use? Do I work backwards because of the nesting?
If you are learning SQL, learn to use correct and explicit join syntax. So your first query would be:
SELECT r.RobberID, a.Nickname, a.NoYears, a.BankName, a.Share
FROM info.Robber r JOIN
info.Accomplices a
on r.RobberID = a.RobberID;
The second:
SELECT a.Nickname, a.NoYears, COUNT(*) as NumRobberies, SUM(Share) as TotalEarnings
FROM info.Robber r JOIN
info.Accomplices a
on r.RobberID = a.RobberID
GROUP BY a.Nickname, a.NoYears
And the third:
WITH ActiveRobbers2 as (
SELECT a.Nickname, a.NoYears, COUNT(*) as NumRobberies, SUM(Share) as TotalEarnings
FROM info.Robber r JOIN
info.Accomplices a
on r.RobberID = a.RobberID
GROUP BY a.Nickname, a.NoYears
)
SELECT a.*
FROM ActiveRobbers2 a
WHERE NoYears = 0 AND
NumRobberies > (SELECT AVG(NumRobberies) FROM ActiveRobbers2);
Actually, I would write the third version using window functions, but I'm leaving your logic as it is in the question.

Select Count of one table into another

I have one SQL statement as:
SELECT ARTICLES.NEWS_ARTCL_ID, ARTICLES.NEWS_ARTCL_TTL_DES,
ARTICLES.NEWS_ARTCL_CNTNT_T, ARTICLES.NEWS_ARTCL_PUB_DT,
ARTICLES.NEWS_ARTCL_AUTH_NM, ARTICLES.NEWS_ARTCL_URL, ARTICLES.MEDIA_URL,
ARTICLES.ARTCL_SRC_ID, SOURCES.ARTCL_SRC_NM, MEDIA.MEDIA_TYPE_DESCRIP
FROM
RSKLMOBILEB2E.NEWS_ARTICLE ARTICLES,
RSKLMOBILEB2E.MEDIA_TYPE MEDIA,
RSKLMOBILEB2E.ARTICLE_SOURCE SOURCES
WHERE ARTICLES.MEDIA_TYPE_IDENTIF = MEDIA.MEDIA_TYPE_IDENTIF
AND ARTICLES.ARTCL_SRC_ID = SOURCES.ARTCL_SRC_ID
AND ARTICLES.ARTCL_SRC_ID = 1
ORDER BY ARTICLES.NEWS_ARTCL_PUB_DT
Now I need to combine another SQL statement into one which is:
SELECT COUNT ( * )
FROM RSKLMOBILEB2E.NEWS_LIKES LIKES, RSKLMOBILEB2E.NEWS_ARTICLE ARTICLES
WHERE LIKES.NEWS_ARTCL_ID = ARTICLES.NEWS_ARTCL_ID
Basically I have one table which contains articles and I need to include the user likes which is in another table.
Use a subquery to add the likescount in your first query like this:
SELECT ARTICLES.NEWS_ARTCL_ID
,ARTICLES.NEWS_ARTCL_TTL_DES
,ARTICLES.NEWS_ARTCL_CNTNT_T
,ARTICLES.NEWS_ARTCL_PUB_DT
,ARTICLES.NEWS_ARTCL_AUTH_NM
,ARTICLES.NEWS_ARTCL_URL
,ARTICLES.MEDIA_URL
,ARTICLES.ARTCL_SRC_ID
,SOURCES.ARTCL_SRC_NM
,MEDIA.MEDIA_TYPE_DESCRIP
,(
SELECT COUNT(*)
FROM RSKLMOBILEB2E.NEWS_LIKES LIKES
WHERE LIKES.NEWS_ARTCL_ID = ARTICLES.NEWS_ARTCL_ID
) AS LikesCount
FROM RSKLMOBILEB2E.NEWS_ARTICLE ARTICLES
,RSKLMOBILEB2E.MEDIA_TYPE MEDIA
,RSKLMOBILEB2E.ARTICLE_SOURCE SOURCES
WHERE ARTICLES.MEDIA_TYPE_IDENTIF = MEDIA.MEDIA_TYPE_IDENTIF
AND ARTICLES.ARTCL_SRC_ID = SOURCES.ARTCL_SRC_ID
AND ARTICLES.ARTCL_SRC_ID = 1
ORDER BY ARTICLES.NEWS_ARTCL_PUB_DT;
I'm not sure what you are trying to achieve but it seems you want to count all the data from 2 tables. You can edit your query to something like this.
SELECT COUNT (ARTICLES.*) FROM RSKLMOBILEB2E.NEWS_LIKES LIKES
JOIN RSKLMOBILEB2E.NEWS_ARTICLE ARTICLES
ON LIKES.NEWS_ARTCL_ID = ARTICLES.NEWS_ARTCL_ID
I think that solution is in using Analytic Functions. Please have a look on https://oracle-base.com/articles/misc/analytic-functions
Please check following query (keep in mind I have no idea about your table structures). Due to left join records might be duplicated, this is why grouping is added.
SELECT ARTICLES.NEWS_ARTCL_ID, ARTICLES.NEWS_ARTCL_TTL_DES,
ARTICLES.NEWS_ARTCL_CNTNT_T, ARTICLES.NEWS_ARTCL_PUB_DT,
ARTICLES.NEWS_ARTCL_AUTH_NM, ARTICLES.NEWS_ARTCL_URL, ARTICLES.MEDIA_URL,
ARTICLES.ARTCL_SRC_ID, SOURCES.ARTCL_SRC_NM, MEDIA.MEDIA_TYPE_DESCRIP,
count(LIKES.ID) over ( partition by ARTICLES.NEWS_ARTCL_ID ) as num_likes
FROM RSKLMOBILEB2E.NEWS_ARTICLE ARTICLES
join RSKLMOBILEB2E.MEDIA_TYPE MEDIA
on ARTICLES.MEDIA_TYPE_IDENTIF = MEDIA.MEDIA_TYPE_IDENTIF
join RSKLMOBILEB2E.ARTICLE_SOURCE SOURCES
on ARTICLES.ARTCL_SRC_ID = SOURCES.ARTCL_SRC_ID
LEFT JOIN RSKLMOBILEB2E.NEWS_LIKES LIKES
ON LIKES.NEWS_ARTCL_ID = ARTICLES.NEWS_ARTCL_ID
WHERE
ARTICLES.ARTCL_SRC_ID = 1
group by ARTICLES.NEWS_ARTCL_ID, ARTICLES.NEWS_ARTCL_TTL_DES,
ARTICLES.NEWS_ARTCL_CNTNT_T, ARTICLES.NEWS_ARTCL_PUB_DT,
ARTICLES.NEWS_ARTCL_AUTH_NM, ARTICLES.NEWS_ARTCL_URL, ARTICLES.MEDIA_URL,
ARTICLES.ARTCL_SRC_ID, SOURCES.ARTCL_SRC_NM, MEDIA.MEDIA_TYPE_DESCRIP
ORDER BY ARTICLES.NEWS_ARTCL_PUB_DT
I also changed coma-separated list of tables from where condition to joins. I think this is more readable since table join conditions are separated from result filtering in where clause.

Rails 3.2 - How to turn this complex query to be in parameterized format?

I am currently helping out a Rails 3.2 project.
Got this complex query that I would like to be in parameterized format.
project.supporters.connection.select_all( "SELECT t2.* FROM
(SELECT MAX(id) AS max_supporter_id FROM supporters WHERE
supporters.project_id = ? GROUP BY supporters.supporter_id) AS
t1 INNER JOIN supporters AS t2 ON t1.max_supporter_id =
t2.id", 1).
Above query is what I would like to be like but I know it doesn't work because select_all doesn't do parameterized query.
So far this is what I got:
project.supporters.group(:supporter_id).maximum(:id) which will
generate this sql: SELECT MAX("supporters"."id") AS maximum_id,
supporter_id AS supporter_id FROM "supporters" WHERE
"supporters"."project_id" = 1 GROUP BY supporter_id
But I haven't made significant progress to do the inner join and finally have the outer SELECT.
Can anyone help?
project_id = 1
supporters = Arel::Table.new(:supporters)
max_id = supporters.project(supporters[:id].maximum.as('max_supporters_id')).group(supporters[:supporter_id])
query = supporters.project(max_id)
.join(supporters[:project_id])
.on(supporters[:max_supporter_id].eq(supporters[:id]))
.where(supporters[:project_id].eq(project_id))
query.to_sql
# => "SELECT (SELECT MAX(\"supporters\".\"id\") AS max_supporters_id FROM \"supporters\" GROUP BY \"supporters\".\"supporter_id\") FROM \"supporters\" INNER JOIN \"supporters\".\"project_id\" ON \"supporters\".\"max_supporter_id\" = \"supporters\".\"id\" WHERE \"supporters\".\"project_id\" = 1"
query.to_a # executes the query and returns records
For more informations about building the complex queries in rails, you could read there https://github.com/rails/arel
I wish it helps.

SQL query for filtering data

I`m working on some sql queries to get some data out of a table; I have made 2 queries for the
same data but both give another result. The 2 queries are:
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN (
( patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id) AND
(patient.Sample = Samples.Sample)
) ON
(tissue.Sample_Name = data_overview.Sample_Name) AND
(tissue.Sample_Name = patient.Sample_Name)
WHERE data_overview.Sentrix_ID= 1416198
OR data_overview.Pool_ID='GS0005701-OPA'
OR data_overview.Pool_ID='GS0005702-OPA'
OR data_overview.Pool_ID='GS0005703-OPA'
OR data_overview.Pool_ID='GS0005704-OPA'
OR data_overview.Sentrix_ID= 1280307
ORDER BY Samples.Sample;")
And the other is
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN
(
(patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id)
AND (patient.Sample = Samples.Sample)) ON
(tissue.Sample_Name = data_overview.Sample_Name)
AND (tissue.Sample_Name = patient.Sample_Name)
WHERE ((
(data_overview.Sentrix_ID)=1280307)
AND (
(data_overview.Pool_ID)="GS0005701-OPA"
OR (data_overview.Pool_ID)="GS0005702-OPA"
OR (data_overview.Pool_ID)="GS0005703-OPA"
OR (data_overview.Pool_ID)="GS0005704-OPA"))
OR (((data_overview.Sentrix_ID)=1416198))
ORDER BY data_overview.Sample;
The one in the top is working quite well but it still won't filter the sentrix_ID.
The second 1 is created with Access but when I try to run this Query in R it gave
a unexpected symbol error. So if anyone knows how to create a query that filter POOL_ID and Sentrix_id with the given parameters thanks in advance
Is it a case of making the where clause something like this:
WHERE Sentrix_ID = 1280307 AND (Pool_ID = 'VAL1' OR Pool_ID = 'VAL2' OR Pool_ID = 'VAL3')
i.e. making sure you have brackets around the "OR" components?
Maybe you meant:
...
WHERE data_overview.Sentrix_ID IN (1280307,1416198 )
AND data_overview.Pool_ID IN ("GS0005701-OPA", "GS0005702-OPA", "GS0005703-OPA" ,"GS0005704-OPA")
;