I have 2 working sets of subqueries. I'm trying to make them into one query with these fields:
select tos.source_system_order_id , tos.TOS_Date, tos.TOS_Final_Charge_Amt_Sum , oes.OES_Final_Charge_Amt_Sum
first query:
SELECT tos1.source_system_order_id,
tos1.tos_date,
SUM(tos1.tos_final_charge_amt_sum)
FROM (SELECT source_system_order_id,
source_system_cd,
To_char(billing_month_dt, 'YYYYMM') AS TOS_Date,
tos_final_charge_amt_sum
FROM tl_ov_stage
ORDER BY source_system_order_id) TOS1
GROUP BY tos1.source_system_order_id,
tos1.tos_date
2ndquery
SELECT OES1.source_system_order_id,
oes1.oes_date,
SUM(oes1.oes_final_charge_amt_sum) AS OES_Final_Charge_Amt_Sum
FROM (SELECT To_char("date", 'YYYYMM') AS OES_Date,
To_char("service order id") AS SOURCE_SYSTEM_ORDER_ID,
oes_final_charge_amt_sum
FROM v_ord_valuation_detail#prodr_link) OES1
GROUP BY OES1.source_system_order_id,
oes1.oes_date,
oes1.order_status
Try using CTE to combine the two select queries. I find CTE is more readable in such cases
with tos
as
(
SELECT tos1.source_system_order_id,
tos1.tos_date,
SUM(tos1.tos_final_charge_amt_sum)
FROM (SELECT source_system_order_id,
source_system_cd,
To_char(billing_month_dt, 'YYYYMM') AS TOS_Date,
tos_final_charge_amt_sum
FROM tl_ov_stage
ORDER BY source_system_order_id) TOS1
GROUP BY tos1.source_system_order_id,
tos1.tos_date
),
OES as
(
SELECT OES1.source_system_order_id,
oes1.oes_date,
SUM(oes1.oes_final_charge_amt_sum) AS OES_Final_Charge_Amt_Sum
FROM (SELECT To_char("date", 'YYYYMM') AS OES_Date,
To_char("service order id") AS SOURCE_SYSTEM_ORDER_ID,
oes_final_charge_amt_sum
FROM v_ord_valuation_detail#prodr_link) OES1
GROUP BY OES1.source_system_order_id,
oes1.oes_date,
oes1.order_status
)
select tos.source_system_order_id,
tos.TOS_Date,
tos.TOS_Final_Charge_Amt_Sum,
oes.OES_Final_Charge_Amt_Sum
from tos
inner join oes
on tos.source_system_order_id = oes.source_system_order_id
AND tos.tos_date = oes.oes_date -- Remove if this is not needed
Related
I have this query in Apache Phoenix SQL:
select WO.* from (
select "nr_id", "txt_commrcial_label"
from "e_application" APP
where "txt_commrcial_label" in ('a','b')
and "nr_id" not in (select "nr_ap_id"
from "e_workorder"
where "nr_id" in ('888'))
and "epochtimestampchanged" = (select max("epochtimestampchanged")
from "e_application"
where "nr_id" = APP."nr_id") ) as APP2,
--
(select Y.ID as WO_ID, Y."nr_id" as WO_nr_id, Y."nr_ap_id" as WO_nr_ap_id
from ( select "nr_id", max("epochtimestampchanged") as max_epochtimestampchanged
from "e_workorder"
where CAST(TO_NUMBER("epochtimestampchanged") AS TIMESTAMP) < TO_TIMESTAMP('2020-10-21 19:22:20.0')
group by "nr_id" ) as X, "e_workorder" as Y
where Y."nr_id" = X."nr_id"
and Y."epochtimestampchanged" < X.max_epochtimestampchanged ) as WO
--
where APP2."nr_id" = WO.WO_nr_ap_id;
I get java language illegal ... blurb for this not overly complex statement. But I cannot see the reason here or in the manuals.
The individual queries work (imagine the ( and , are not there), but no joy when these 2 sub-queries merged to a JOIN.
Do I need to persist the results to tables and then JOIN? Or is there way around this? I have the impression this is too complex in terms of sub-queries.
For others to note, this is a big and a different SQL Approach is needed as per below which is a work-around with note from Cloudera:
The best workaround is to explicitly define a join in the APP2 query.
See the APP_MAX_TIMESTAMP table joined with the APP table, defining
basically the same condition as in the original query (but using a
table join instead of an inner select):
The query that should work and should do the same as the original
query:
select
WO.*
from
(
select
"nr_id",
"txt_commrcial_label"
from
"e_application" APP
LEFT JOIN (
select
max("epochtimestampchanged") as max_app_timestamp,
"nr_id" as max_app_timestamp_nr_id
from
"e_application"
group by "nr_id"
) APP_MAX_TIMESTAMP
ON APP_MAX_TIMESTAMP.max_app_timestamp_nr_id = APP."nr_id"
where
"txt_commrcial_label" in
( list
)
and "nr_id" not in
(
select
"nr_ap_id"
from
"e_workorder"
where
"nr_id" in
(
'888'
)
)
and "epochtimestampchanged" = max_app_timestamp
)
as APP2,
(
select
Y.ID as WO_ID,
Y."nr_id" as WO_nr_id,
Y."nr_ap_id" as WO_nr_ap_id
from
(
select
"nr_id",
max("epochtimestampchanged") as max_epochtimestampchanged
from
"e_workorder"
where
CAST(TO_NUMBER("epochtimestampchanged") AS TIMESTAMP) < TO_TIMESTAMP('2022-10-10 19:22:20.0')
group by
"nr_id"
)
as X,
"e_workorder" as Y
where
Y."nr_id" = X."nr_id"
and Y."epochtimestampchanged" < X.max_epochtimestampchanged
)
as WO
where
APP2."nr_id" = WO.WO_nr_ap_id;
I want to apply the group by function based on columns generated by the PIVOT function.
In the query below, I wanted to apply Sum(TC.MB_Usage) so I could use group by at the end. However I am unable to apply the group by function to columns that are generated by the PIVOT function (SITES).
Comments are mentioned in BOLD
With TC as(
select /*+ NO_MERGE(T1) NO_MERGE(T2)
PARALLEL(T1,4) PARALLEL(T2,4) */
T1.* from (
select /*+
DRIVING_SITE(A) NO_MERGE(A) NO_MERGE(fips) NO_MERGE(fw) PARALLEL(A,4)
PARALLEL(fips,4) PARALLEL(fw,4) */
distinct
resource_value,
resource_type,
L3_IMSI as IMSI
,L9_Calling_Number as MDN
,L9_ECID as Curr_ECID
,trunc(START_TIME) as Usage_Date
,trim(TO_CHAR (TO_NUMBER (SUBSTR (L9_ECID,1,LENGTH(L9_ECID) - 2 ),'XXXXXXXXX'),'000000')) as enodeb
,substr(trim(TO_CHAR (TO_NUMBER (SUBSTR (L9_ECID,1,LENGTH(L9_ECID) - 2 ),'XXXXXXXXX'),'000000')),1,2) as fips_cd
,STATE_CODE
,STATE_NAME
,Sum(L3_ROUNDED_UNIT/1024) as MB_Usage
from RT_ET A
INNER JOIN
FIPS_STATEfips
ON trim(to_char(fips.FIPS_CODE,'00')) = substr(trim(TO_CHAR (TO_NUMBER (SUBSTR (A.L9_ECID,1,LENGTH(A.L9_ECID) - 2 ),'XXXXXXXXX'),'000000')),1,2)
INNER JOIN
DVC_ADDRfw
ON trim(L3_IMSI) = trim(to_char(FW.IMSI))
Where A.L9_ECID not in (' ','0') AND A.L3_IMSI not in (' ','0')
AND trunc(A.start_time) > trunc(sysdate-8)
AND trunc(start_time) > trunc(FW.ODS_INSERT_DATE)
group by
resource_value
,resource_type
,L3_IMSI
,L9_Calling_Number
,L9_ECID
,trunc(START_TIME)
,trim(TO_CHAR (TO_NUMBER (SUBSTR (L9_ECID,1,LENGTH(L9_ECID) - 2 ),'XXXXXXXXX'),'000000'))
,substr(trim(TO_CHAR (TO_NUMBER (SUBSTR (L9_ECID,1,LENGTH(L9_ECID) - 2 ),'XXXXXXXXX'),'000000')),1,2)
,STATE_CODE
,STATE_NAME
) T1
where NOT EXISTS (
SELECT
1 FROM DVC_ENODEB T2
WHERE T1.IMSI = trim(to_char(T2.IMSI))
AND T1.MDN = T2.MDN
AND T1.ENODEB = T2.ENODEB
)
)
select
distinct
SITES.*,
TC.resource_value,
TC.resource_type,
TC.IMSI,
TC.MDN,
TC.Curr_ECID,
TC.Usage_Date,
TC.enodeb,
TC.fips_cd,
TC.STATE_CODE,
TC.STATE_NAME,
**TC.MB_Usage -- Need to apply Sum(TC.MB_Usage)**
from
(
with
endb as
(select
e.IMSI, e.MDN,e.site_id, E.ENODEB,
ROW_NUMBER ()OVER (PARTITION BY e.IMSI||e.MDN
ORDER BY e.IMSI||e.MDN ) row_id
from
FIXED_WIRELESS_DVC_ADDR_ENODEB e
)
select *
from (select IMSI,MDN,IMSI||MDN as IMSI_MDN,site_id,row_id
from endb
)
pivot (max(site_id) siteid for row_id in (1,2,3,4,5,6,7,8,9,10,11,12,13)) ) SITES
INNER JOIN TC
ON ((TC.IMSI = trim(to_char(SITES.IMSI))) AND TC.MDN = SITES.MDN)
**Unable to apply Group by
based on below PIVOT columns (SITES.*), if I use SUM for MD_USAGE
Group BY
TC.resource_value,
TC.resource_type,
TC.IMSI,
TC.MDN,
TC.Curr_ECID,
TC.Usage_Date,
TC.enodeb,
TC.fips_cd,
TC.STATE_CODE,
TC.STATE_NAME,
SITES.***
You will need to specify the individual columns in your GROUP BY.
It looks like your SITES alias will have the columns IMSI, MDN, IMSI_MDN, and then 1,2,3,4,5,6,7,8,9,10,11,12,13 from the PIVOT clause.
So try listing those individually, and for the numeric ones put them in quotes:
GROUP BY
...
SITES."1", SITES."2", etc.
The code below joins two tables and I need to extract only the latest date per account, though it holds multiple accounts and history records. I wanted to use the MAX function, but not sure how to incorporate it for this case. I am using My SQL server.
Appreciate any help !
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from
Property.dbo.PROP
inner join
Property.dbo.PROP_DATA on Property.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where
(PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
order by
PROP.EffDate DESC
Assuming your DBMS supports windowing functions and the with clause, a max windowing function would work:
with all_data as (
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label,
max (PROP.EffDate) over (partition by PROP.PolNo) as max_date
from Actuarial.dbo.PROP
inner join Actuarial.dbo.PROP_DATA
on Actuarial.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where (PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
)
select
FileName, InsName, Status, FileTime, SubmissionNo,
PolNo, EffDate, ExpDate, Region, UnderWriter, Data, Label
from all_data
where EffDate = max_date
ORDER BY EffDate DESC
This also presupposes than any given account would not have two records on the same EffDate. If that's the case, and there is no other objective means to determine the latest account, you could also use row_numer to pick a somewhat arbitrary record in the case of a tie.
Using straight SQL, you can use a self-join in a subquery in your where clause to eliminate values smaller than the max, or smaller than the top n largest, and so on. Just set the number in <= 1 to the number of top values you want per group.
Something like the following might do the trick, for example:
select
p.FileName
, p.InsName
, p.Status
, p.FileTime
, p.SubmissionNo
, p.PolNo
, p.EffDate
, p.ExpDate
, p.Region
, p.Underwriter
, pd.Data
, pd.Label
from Actuarial.dbo.PROP p
inner join Actuarial.dbo.PROP_DATA pd
on p.FileID = pd.FileID
where (
select count(*)
from Actuarial.dbo.PROP p2
where p2.FileID = p.FileID
and p2.EffDate <= p.EffDate
) <= 1
and (
pd.Label in ('Occupancy' , 'OccupancyTIV')
and p.Status = 'Bound'
)
ORDER BY p.EffDate DESC
Have a look at this stackoverflow question for a full working example.
Not tested
with temp1 as
(
select foo
from bar
whre xy = MAX(xy)
)
select PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from Actuarial.dbo.PROP
inner join temp1 t
on Actuarial.dbo.PROP.FileID = t.dbo.PROP_DATA.FileID
ORDER BY PROP.EffDate DESC
I am working with a tool that would extract some data from an Access Database. So basically, i am working on a query to get this data.
Below is the code i am currently working on.
I am getting an error: Syntax error in FROM clause
I can't seem to find where the query is going wrong. I would appreciate any help! Thank youu.
EDIT: putting my actual query
SELECT table_freq.*, IIF(table_freq.txn_ctr > (table_ave_freq.ave_freq * 3), "T", "F") as suspicious_flag
FROM
(
SELECT tbl_TransactionHistory.client_num, tbl_TransactionHistory.client_name,
tbl_TransactionHistory.transaction_date, Count(tbl_TransactionHistory.client_num) AS txn_ctr
FROM tbl_TransactionHistory
GROUP BY tbl_TransactionHistory.client_num, tbl_TransactionHistory.client_name,
tbl_TransactionHistory.transaction_date
) AS table_freq
INNER JOIN
(
SELECT table_total_freq.client_num, total_txn_ctr as TotalTransactionFrequency, total_no_days as TotalTransactionDays,
(table_total_freq.total_txn_ctr)/(table_no_of_days.total_no_days) AS ave_freq
FROM
(
(
SELECT client_num, SUM(txn_ctr) AS total_txn_ctr
FROM
(
SELECT client_num, client_name, transaction_date, COUNT(client_num) AS txn_ctr
FROM tbl_TransactionHistory
GROUP BY client_num, client_name, transaction_date
) AS tabFreq
GROUP BY client_num
) AS table_total_freq
INNER JOIN
(
SELECT client_num, COUNT(txn_date) as total_no_days
FROM
(
SELECT DISTINCT(transaction_date) as txn_date, client_num
FROM tbl_TransactionHistory
ORDER BY client_num
) AS table1
GROUP BY client_num
) AS table_no_of_days
ON table_total_freq.client_num = table_no_of_days.client_num
)
) AS table_ave_freq
ON table_freq.client_num = table_ave_freq.client_num
I have a table called TaskLog that holds the results of various scheduled tasks. It has (for the purposes of this question) these columns:
TaskLogID: unique ID for this record
TaskID: ID of the task that ran
HostName: name of the host on which it ran
RunDate: date and time on which the task was run
Output: output of this run
In order to get the output from the latest run of each task, I had been executing multiple queries, until I worked out this single query which is much faster:
SELECT TaskLog.TaskID, TaskLog.HostName, TaskLog.Output
FROM TaskLog
INNER JOIN (
SELECT TaskLogID, TaskID, HostName, MAX(RunDate)
FROM TaskLog
GROUP BY TaskID, HostName
) AS Latest
USING (TaskLogID)
Now I'd like to get the output from each of the last N runs of each task, for some fixed N, instead of just the latest run. Is there a way to do this in a single query?
TIA
Untested as I don't have MySQL installed on this machine (based on here)
select TaskLogID,
TaskID,
HostName,
RunDate
from (select TaskLogID,
TaskID,
HostName,
RunDate,
#num := if(#group = concat(TaskID, HostName), #num + 1, 1) as row_number,
#group := concat(TaskID, HostName) as dummy
from TaskLog) as x
where row_number <= 5;
This is where MySQL lack of window functions such as Row_Number() really hurts.
Select T.TaskLogId, T.TaskId, T.HostName, T.RunDate
From TaskLog As T
Join (
Select T1.TaskLogId
, (Select Count(*)
From TaskLog as T2
Where T2.TaskId = T1.TaskId
And T2.RunDate < T1.RunDate) + 1 As Rnk
From TaskLog As T1
) As RankedTasks
On RankedTasks.TaskLogId = T.TaskLogId
And RankedTasks.Rnk <= <somevalue>
Order By T.TaskId, T.RunDate
ADDITION
Assuming that TaskLogId is an auto increment column, you might be able to something like the following (In this example, I assumed you requested the top 5 items):
Select T.TaskLogId, T.TaskId, T.HostName, T.RunDate
From TaskLog As T
Join (
Select Tasks1.TaskId
, (
Select T4.TaskLogId
From TaskLog As T4
Where T4.TaskId = Tasks.TaskId
Order By T4.RunDate Desc
Limit 5, 1
) As UpperTaskLogId
From (
Select T3.TaskId
From TaskLog As T3
Group By T3.TaskId
) As Tasks1
) As LastId
On LastId.TaskId = T.TaskId
And LastId.UpperTaskLogId >= T.TaskLogId