How to use BigQuery's union all with an inner join? - sql

I am attempting to join all comment tables (shards of comments each month) to a posts table. Is there a way for me to perform a union all before the inner join? Details on the union all operator can be found in the documentation here. My query with only 1 of the comments table is as follows:
SELECT c.score, c.body, c.link_id, c.parent_id, p.created_utc, c.created_utc
FROM [fh-bigquery:reddit_comments.2016_01] AS c
INNER JOIN [fh-bigquery:reddit_posts.full_corpus_201512] AS p
ON c.parent_id = p.name
WHERE SUBSTR(c.parent_id, 1, 2) = 't3'
ORDER BY c.score DESC
LIMIT 10

Replace
FROM [fh-bigquery:reddit_comments.2016_01] AS c
with
FROM (
SELECT score, body, link_id, parent_id, created_utc
FROM (TABLE_QUERY([fh-bigquery:reddit_comments],
'REGEXP_MATCH(table_id, r"\d{4}_\d{2}")'))
) AS c
Hope, this gives you idea
See more on Table wildcard functions and Regular expression functions

As Mikhail Berlyant pointed out in his answer, modifying the query as such accomplished what I needed.
SELECT c.score, c.body, c.link_id, c.parent_id, p.created_utc, c.created_utc, (c.created_utc - p.created_utc) AS time_diff
FROM (
SELECT *
FROM
[fh-bigquery:reddit_comments.2015_11],
[fh-bigquery:reddit_comments.2015_12],
[fh-bigquery:reddit_comments.2016_01],
) AS c
INNER JOIN [fh-bigquery:reddit_posts.full_corpus_201512] AS p
ON c.parent_id = p.name
WHERE SUBSTR(c.parent_id, 1, 2) = 't3'
ORDER BY c.score DESC
LIMIT 100

Related

How to grouping row value in some conditional postgresql

I have query like this:
SELECT user_input_id,
question_id,
type,
question,
COALESCE(value_text, value_free_text, value_date::text, value_number::text, value) AS all_value
FROM(
SELECT
a.id,
a.user_input_id,
d.id as question_id,
d.type,
d.matrix_subtype,
d.question,
a.value_suggested_row,
c.value as matrix_questions,
a.value_suggested,
b.value,
a.value_text,
a.value_free_text,
a.value_date,
a.value_number
FROM survey_user_input_line a
LEFT JOIN survey_label b on b.id = a.value_suggested
LEFT JOIN survey_label c on c.id = a.value_suggested_row
LEFT JOIN survey_question d on d.id = a.question_id
LEFT JOIN survey_user_input e on e.id = a.user_input_id
WHERE a.survey_id = 6
ORDER BY question_id, a.user_input_id, id, value_suggested_row) as TempTable
and this result:
I would like to grouping row where type is multiple_choice
and my wish result like this:
Can Anyone Help Me?
I would split your result into two part (with and without multiple_choice) and UNION them after grouping the multiple_choice part:
SELECT
*
FROM (--<your query>) s
WHERE type != 'multiple_choice'
UNION
SELECT
user_input_id,
question_id,
type,
question,
STRING_AGG(all_value, ',')
FROM (--<your query>) s
WHERE type = 'multiple_choice'
GROUP BY user_input_id, question_id, type, question
It could be more performant to put your subquery into a CTE:
WITH my_cte AS (
-- <your query>
)
SELECT
*
FROM my_cte
WHERE type != 'multiple_choice'
UNION
SELECT
user_input_id,
question_id,
type,
question,
STRING_AGG(all_value, ',')
FROM my_cte
WHERE type = 'multiple_choice'
GROUP BY user_input_id, question_id, type, question

Nesting queries on JOINS and top1 with ties

I am trying to use the result of the below SQL query-1 such that I can make another JOIN on this with my second query result to retrieve Fundsrc on the common ID - Project.
QUERY 1-
SELECT top 1 with ties
t.project, r.rel_value AS "FundSrc" ,r.date_to
from atsproject t
LEFT OUTER JOIN aglrelvalue r ON(t.client=r.client AND r.rel_attr_id='ZB18' AND r.attribute_id='B0' AND t.project=r.att_value)
WHERE r.date_To > '04/30/2020' and status='n'
ORDER BY row_number() over (partition by t.project order by t.project, r.rel_value)
I cannot put the JOIN inside the above query as it will mess with the result. Instead, if I can do a nesting on this then I think that should solve the issue.
My second query is -
SELECT
t.project,t.work_order as activity, r1.labor_funding_source2_fx AS "Designated Labour Funding"
FROM atsworkorder t
LEFT OUTER JOIN afxactlaborfund r1 ON( t.work_order = r1.dim_value AND t.client = r1.client AND r1.attribute_id = 'BF')
WHERE t.client='PC' and t.status = 'N'
The Output should be -
t.project,t.work_order from query 2 + Fundsrc from Query 1, with the common id on Project ID.
Any suggestions on this is highly appreciated.
You can wrap 'subqueries' in parenthesis and then join them.
Can you try this?:
SELECT *
FROM (
SELECT top 1 with ties t.project,
r.rel_value AS "FundSrc",
r.date_to
FROM atsproject t
LEFT OUTER JOIN aglrelvalue r
ON t.client=r.client
AND r.rel_attr_id='ZB18'
AND r.attribute_id='B0'
AND t.project=r.att_value
WHERE r.date_To > '04/30/2020' and status='n'
ORDER BY row_number() over (partition by t.project order by t.project, r.rel_value)
) AS TABLE_1
LEFT JOIN
(
SELECT t.project,
t.work_order as activity,
r1.labor_funding_source2_fx AS "Designated Labour Funding"
FROM atsworkorder t
LEFT OUTER JOIN afxactlaborfund r1
ON t.work_order = r1.dim_value
AND t.client = r1.client
AND r1.attribute_id = 'BF'
WHERE t.client='PC' and t.status = 'N'
) AS TABLE_2
ON TABLE_1.PROJECT = TABLE2.PROJECT
I am pretty sure an ORDER BY clause will not work within a subquery. Thus, this should probably work:
SELECT *
FROM (
SELECT t.project,
r.rel_value AS "FundSrc",
r.date_to,
row_number() over (partition by t.project order by t.project, r.rel_value) AS MY_RANKING
FROM atsproject t
LEFT OUTER JOIN aglrelvalue r
ON t.client=r.client
AND r.rel_attr_id='ZB18'
AND r.attribute_id='B0'
AND t.project=r.att_value
WHERE r.date_To > '04/30/2020' and status='n'
) AS TABLE_1
LEFT JOIN
(
SELECT t.project,
t.work_order as activity,
r1.labor_funding_source2_fx AS "Designated Labour Funding"
FROM atsworkorder t
LEFT OUTER JOIN afxactlaborfund r1
ON t.work_order = r1.dim_value
AND t.client = r1.client
AND r1.attribute_id = 'BF'
WHERE t.client='PC' and t.status = 'N'
) AS TABLE_2
ON TABLE_1.PROJECT = TABLE2.PROJECT
WHERE TABLE_1.MY_RANKING = 1
Note: On your formatting, wrap words within ` when they refer to code. They will look like this.
Wrap blocks of code within three of those (three at the beginning and at the end). It will look like the blocks of code above.

SQL Join two query

I need some help combining these two queries so I can get this in one single view.
Query 1
select t.*, n.caption, n.description
from (
select NodeID,
count(distinct cpuindex) as number_of_cpu,
case
When count(distinct cpuindex) < 8 THEN 1
Else count(distinct cpuindex)/8
End AS number_of_cores
from CPUMultiLoad_Detail (nolock) where nodeid in (select nodeid from nodesdata)
group by NodeID
) as t
inner join NodesData as n (nolock) on n.nodeid = t.nodeid
where n.description NOT Like '%Windows%'
order by n.description
Query 2
SELECT D.Environment, B.Name, C.Caption, A.ComponentStatisticData, A.ErrorMessage
FROM [APM_CurrentStatistics] A, APM_Application B, NodesData C
join NodesCustomProperties D on D.NodeID= C.NodeID
WHERE
A.ApplicationID=B.ID AND
A.NodeID=C.NodeID AND
B.Name IN ('Oracle Database Licensing')
I want to join first query and second query so I have CPU Information and Licensing Information in same table. How do I join both query? We can use common key Nodes.NodeID to join and not sure how. Any help will be greatly appreciated.
Consider joining the inner aggregate subquery of first query which holds distinct NodeID to the second query using a CTE. Additionally, use explicit JOIN(current standard in SQL) and heed bad habits to kick : using table aliases like (a, b, c) and use more informative table aliases.
WITH agg AS
(
select NodeID,
count(distinct cpuindex) as number_of_cpu,
case
when count(distinct cpuindex) < 8 THEN 1
else count(distinct cpuindex) / 8
end AS number_of_cores
from CPUMultiLoad_Detail
where nodeid in (select nodeid from nodesdata)
group by NodeID
)
SELECT cp.Environment, app.Name, n.Caption,
cs.ComponentStatisticData, cs.ErrorMessage,
agg.NodeID, agg.number_of_cpu, agg.number_of_cores, n.description
FROM APM_CurrentStatistics cs
INNER JOIN APM_Application app
ON cs.ApplicationID = app.ID
AND app.Name IN ('Oracle Database Licensing')
INNER JOIN NodesData n
ON cs.NodeID = n.NodeID
AND n.description NOT LIKE '%Windows%'
INNER JOIN NodesCustomProperties cp
ON cp.NodeID = n.NodeID
INNER JOIN agg
ON cs.NodeID = agg.NodeID
ORDER BY n.description

Oracle SQL - Select from two tables

I have two tables which are exactly the same layout, but have different data (one is current, one is history).
How do I pull information from both tables?
PSUDO SQL:
SELECT
T.TRANS_QUAN,
P.PONO, D.ID
FROM
TRANSLOG T, (select * from PO, PO_HIST) P, (SELECT * FROM PO_DETAIL, PO_DETAIL_HIST) D
WHERE
D.PO_ID = P.ID
AND T.SOURCE_ID = D.ID
When I try to actually run that I get "column ambiguously defined"
You can UNION clause.
Try:
SELECT
T.TRANS_QUAN,
P.PONO, D.ID
FROM
TRANSLOG T,
(
SELECT * FROM PO
UNION
SELECT * FROM PO_HIST
) P,
(
SELECT * FROM PO_DETAIL
UNION
SELECT * FROM PO_DETAIL_HIST
) D
WHERE
D.PO_ID = P.ID
AND T.SOURCE_ID = D.ID
(select * from PO, PO_HIST) P
This subquery might make a cross join of tables that share a common column name.
Maybe you want:
Select t.trang_quan
, p.pono
, d.id
from translog t
inner join po_detail d
on d.id = t.source_id
cross join po_detail_hist
inner join po p
on p.id = d.po_id
cross join po_hist p2
Are you sure you want cross joins?

SQL Server: select based on the latest id in a many to n:m relationship

What i need to do is select the comment details and the last action taken on the comment; I have 3 tables:
Comment
CommentID, commentText, userID, date_posted
Action
ActionID, action_taken,userID,date_actioned
and CommentJoinAction
id,ActionID,CommentID
There can be one comment, but many actions on the comment.
my SQL is looking something like:
Select /*snip comment details and such*/
From Comment
Inner Join (select max(actionid) from commentjoinaction) as cja on /*blah cause you know from reading this, it won't work*/
So what is it that I can do so that I always pick up the latest commentAction for the comments.
many thanks
SELECT t.commentText, t.action_taken
FROM (SELECT c.commentText, a.action_taken,
ROW_NUMBER() OVER (PARTITION BY c.CommentID ORDER BY a.date_actioned DESC) AS RowNum
FROM Comment c
INNER JOIN CommentJoinAction cja
ON c.CommentID = cja.CommentID
INNER JOIN Action a
ON cja.ActionID = a.ActionID
) t
WHERE t.RowNum = 1
Is this what you are looking for?
SELECT
/*Select desired fields*/
FROM Comments AS C
INNER JOIN (
SELECT
CommentID
,MAX(ActionID) AS ActionID
FROM CommentJoinAction
GROUP BY CommentID
)AS CJA
ON C.CommentID = CJA.CommentID
INNER JOIN ACTION AS A
ON CJA.ActionID = A.ActionID
select C.*, A.* from Comment C
inner join
(
select CommentID, Max(ActionID) as LatestActionID from CommentJoinAction
group by CommentID
) CJA on C.CommentID = CJA.CommentID
inner join Action A on CJA.LatestActionID = A.ActionID
If you just want the actionID
select c.*, (
select max(actionID)
from CommentJoinAction cja
where cja.commentID = c.commentID
) as maxActionID
from Comment c
Or if you want all the Action fields:
select c.*, a.*
from Comment c
inner join Action a
on a.actionID = (
select max(actionID)
from CommentJoinAction
where commentID = c.commentID
)