Using trunc and concatenate command with Join - sql

select EDR_Process_Time, MSISDN1, Total_payment/Total_data_MB from
(
select trunc(M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time) as EDR_Process_Time, M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN as MSISDN1, trunc(M_MOBILEMV.Q_RA_CDR_DETAILS_V.CDR_start_Date), M_MOBILEMV.Q_RA_CDR_DETAILS_V.served_msisdn, sum(M_MOBILEMV.Q_RA_CDR_DETAILS_V.charge_fee_1) as Charge_fee_CDR,
sum(M_MOBILEMV.Q_RA_EDR_DETAILS_V.charge_fee/100) as Total_Payment,
sum(M_MOBILEMV.Q_RA_EDR_DETAILS_V.amount/1048576) as Total_data_MB,
from (M_MOBILEMV.Q_RA_EDR_DETAILS_V
left join M_MOBILEMV.Q_RA_CDR_DETAILS_V on concat(trunc(M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time), M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN) = concat(trunc(M_MOBILEMV.Q_RA_CDR_DETAILS_V.CDR_start_date), M_MOBILEMV.Q_RA_CDR_DETAILS_V.served_MSISDN))
group by trunc(M_MOBILEMV.Q_RA_EDR_DETAILS_V.Process_time), M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN
group by trunc(M_MOBILEMV.Q_RA_CDR_DETAILS_V.CDR_start_Date), M_MOBILEMV.Q_RA_CDR_DETAILS_V.Served_MSISDN
)

Syntax of functions is wrong. Use trunc function as trunc(M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time). Usege of sum is wrong too. You also should change them to sum(M_MOBILEMV.Q_RA_CDR_DETAILS_V.charge_fee_1.

First, wrong syntax at M_MOBILEMV.Q_RA_EDR_DETAILS_V.sum((charge_fee)/100) and other similar expressions.
If you want sum of charge_fee/100 column of the M_MOBILEMV.Q_RA_EDR_DETAILS_V table (view) it must
be
sum(M_MOBILEMV.Q_RA_EDR_DETAILS_V.charge_fee/100)
Next, you can not use an alias in the same SELECT list where it was introduced. Total_Payment and Total_data_MB should only apprear in expressions at outer SELECT.
Assign aliases to the every expression of the inner select, an alias to the inner select itself and use list of qualified names and expresions using those names instead of * in the outer select.
Also, it looks like GROUP BY is missing.
select t.process_time, t.MSISDN, t.sum1,
t.Total_Payment,
t.Total_data_MB,
t.Total_Payment/t.Total_data_MB as cost_per_MB
from (
select
M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time,
M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN,
sum(M_MOBILEMV.Q_RA_CDR_DETAILS_V.charge_fee_1) as sum1,
(coalesce(sum(M_MOBILEMV.Q_RA_CDR_DETAILS_V.charge_fee_1),0) + coalesce(sum(M_MOBILEMV.Q_RA_EDR_DETAILS_V.charge_fee/100),0)) as Total_Payment,
sum(M_MOBILEMV.Q_RA_EDR_DETAILS_V.amount)/1048576 as Total_data_MB
-- Don't you mean
--GROUP BY M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time, M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN
from (M_MOBILEMV.Q_RA_EDR_DETAILS_V
left join M_MOBILEMV.Q_RA_CDR_DETAILS_V on concat(trunc(M_MOBILEMV.Q_RA_EDR_DETAILS_V.process_time), M_MOBILEMV.Q_RA_EDR_DETAILS_V.MSISDN) = concat(trunc(M_MOBILEMV.Q_RA_CDR_DETAILS_V.CDR_start_date), M_MOBILEMV.Q_RA_CDR_DETAILS_V.served_MSISDN)
) t
)

Related

Joining a group by subquery with substr columns

I am trying to join a group by subquery with another table but am running in to issues since the subquery contains aliases which are only valid within the subquery. The issue is that the AREA table only has the 3 digit locker id embedded as part of a longer string in the ARE_CODE column which is why I am using substr. Here is the group by subquery:
SELECT SUBSTR(ARE_CODE,0,3) AS "Locker", COUNT(ARE_UID) AS "Qty"
FROM AREA
WHERE SUBSTR(ARE_CODE,0,1)='L'
GROUP BY SUBSTR(ARE_CODE,0,3)
It runs fine on its own - the problem is that I am trying to join this with another table in the main query. The alias is only valid within the subquery itself and can't be referenced as I did below. I have also tried joining the substr function directly but that doesn't work either.
SELECT P.Locker, P.Permit, L.Qty
FROM PERMITS P
INNER JOIN (SELECT SUBSTR(ARE_CODE,0,3) AS "Locker", COUNT(ARE_UID) AS "Qty"
FROM AREA_LKP
WHERE SUBSTR(ARE_CODE,0,1)='L'
GROUP BY SUBSTR(ARE_CODE,0,3) L ON L.Locker = P.Locker
Any suggestions on how to work around this issue?
You just need to remove the double quotes from the alias as they makes the alias case sensistive and you must have to use them with double quotes wherever you want to use them in your query with exact case.
So better not to use the double quotes for alias untill and unless you want to give the case sensitive name or want space in the alias.
SELECT P.Locker, P.Permit, L.Qty
FROM PERMITS P
INNER JOIN (SELECT SUBSTR(ARE_CODE,0,3) AS Locker, COUNT(ARE_UID) AS Qty
FROM AREA_LKP
WHERE SUBSTR(ARE_CODE,0,1)='L'
GROUP BY SUBSTR(ARE_CODE,0,3) L ON L.Locker = P.Locker
The issue are the double quotes. But your query has other eccentricities:
In strings, the first character is at 1, not 0 (although 0 is allowed).
LIKE is a good way to do string comparisons.
So:
SELECT P.Locker, P.Permit, L.Qty
FROM PERMITS P INNER JOIN
(SELECT SUBSTR(ARE_CODE, 1, 3) AS Locker, COUNT(*) AS Qty
FROM AREA_LKP
WHERE ARE_CODE LIKE 'L%'
GROUP BY SUBSTR(ARE_CODE, 1, 3)
) L
ON L.Locker = P.Locker;
I should note that LIKE permits the use of an index on the column, but SUBSTR() generally prevents that.
Why you`re set the alias of the table at the end of the subquery?
INNER JOIN (SELECT SUBSTR(ARE_CODE,0,3) AS "Locker", COUNT(ARE_UID) AS "Qty"
FROM AREA_LKP
WHERE SUBSTR(ARE_CODE,0,1)='L'
GROUP BY SUBSTR(ARE_CODE,0,3) L
Try:
INNER JOIN (SELECT SUBSTR(ARE_CODE,0,3) AS "Locker", COUNT(ARE_UID) AS "Qty"
FROM AREA_LKP L
WHERE SUBSTR(ARE_CODE,0,1)='L'
GROUP BY SUBSTR(ARE_CODE,0,3)
For sharing expressions between different statements take a look at the with-statement:
https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/with.html
Finally, are you sure that:
L.Locker = P.Locker
Can be evaluated as expected? So is the substringged value of L.Locker same as P.Locker?

Error in using subquery in access join query

I need to use the result of a query as a lookup field for another query. What I tried was using a sub query aliased as something, but finally I got some error saying "enter parameter value" for variz.variz and Y.varizname.
I've searched in forums, but I can't find any similar problem.
SELECT sahmeharkas.attrib,
[sahmeharkas]![expenseper] AS Expense,
variz.variz
FROM sahmeharkas
LEFT JOIN
(SELECT variz.varizname FROM variz GROUP BY variz.varizname) as Y
ON sahmeharkas.attrib = Y.variz.varizname
The table variz does not exist outside of the subquery; you should instead use the subquery alias as the table qualifier, e.g.:
select s.attrib, s.expenseper as expense, y.variz
from
sahmeharkas s left join
(select v.variz, v.varizname from variz v group by v.variz, v.varizname) y on
s.attrib = y.varizname

table alias not work in subquery in oracle

I am generating records with sum aggregate function and subquery, but the alias is not work there in inner query.
my query is
select UPP.item_total,
(select sum(INN.item_value_afs) total_item_value_afs from
(select distinct INN.reg_no,INN.tpt_cuo_nam,INN.item_total,INN.item_value_afs
from sigtasad.customs_import_data INN where INN.reg_no=UPP.reg_no and INN.tpt_cuo_nam=UPP.tpt_cuo_nam)) total_item_value,
sum(UPP.code_tax_amount), UPP.cmp_nam from SIGTASAD.CUSTOMS_IMPORT_DATA UPP where
UPP.reg_no='38699' and UPP.company_tin='9003247336' group by
UPP.reg_no,UPP.tpt_cuo_nam,UPP.cmp_nam,UPP.item_total ;
this query generate this error :
ORA-00904: "UPP"."TPT_CUO_NAM": invalid identifier
I want like this result!!!
Your query has numerous errors and bad habits. For instance:
You qualify a column name with an undefined table alias.
You are aggregating by columns not in the select.
You are using sum() on a subquery that has sum().
Based on the picture that you show, you probably want something like this:
select upp.item_total,
sum(item_value_afs) as total_item_value,
sum(upp.code_tax_amount),
upp.cmp_nam
from SIGTASAD.CUSTOMS_IMPORT_DATA upp
where upp.reg_no = '38699' and upp.company_tin = '9003247336'
group by upp.cmp_nam, upp.item_total ;
Or perhaps:
select upp.item_total,
sum(sum(item_value_afs)) over (partition by upp.cmp_nam, upp.item_total) as total_item_value,
sum(upp.code_tax_amount),
upp.cmp_nam
from SIGTASAD.CUSTOMS_IMPORT_DATA upp
where upp.reg_no = '38699' and upp.company_tin = '9003247336'
group by upp.cmp_nam, upp.item_total ;
Your innermost subquery
(select distinct nn.reg_no,inn.tpt_cuo_nam, inn.item_total, inn.item_value_afs
from sigtasad.customs_import_data inn
where inn.reg_no = upp.reg_no and inn.tpt_cuo_nam = upp.tpt_cuo_nam
)
references a table that is not joined (upp). It also does not have an alias but that problem would come later. Please note, that there also seems to be a type nn.reg_no instead of inn.reg_no
The structure of the tables is not displayed here but fixing the problem would mean something along the lines of:
(select distinct inn.reg_no,inn.tpt_cuo_nam, inn.item_total, inn.item_value_afs
from sigtasad.customs_import_data inn, SIGTASAD.CUSTOMS_IMPORT_DATA upp
where inn.reg_no = upp.reg_no and inn.tpt_cuo_nam = upp.tpt_cuo_nam
)

SQL Syntax Error Group By

I've got a sql syntax and it gives me the error:
Msg 8120, Level 16, State 1, Line 1 Column 'VEHICLEMASTR.cconduction'
is invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
Here is the SQL syntax:
SELECT A.cplateno,A.cconduction,A.cname,A.cbatterymodel
,A.dbattery,A.DlastChange,A.nlastoilkm,A.naveragekmday
,A.dkmreading,A.dfranacq,A.dfranexp,A.nlimit,A.dreading
,CONVERT(varchar(2),month(MAX(B.dinsexp)))+'/'+CONVERT(varchar(2),day(MAX(B.dinsexp)))+'/'+CONVERT(varchar(4),year(MAX(B.dinsexp))) as dinsexp
,C.corno,CONVERT(varchar(2),month(MAX(C.dregexp)))+'/'+CONVERT(varchar(2),day(MAX(C.dregexp)))+'/'+ CONVERT(varchar(4),year(MAX(C.dregexp))) as dregexp
FROM VEHICLEMASTR A
LEFT JOIN VEHICLEINSURANCE B
ON A.cplateno = B.cplateno
LEFT JOIN VREGISTRATION C
ON A.cplateno = C.cplateno
GROUP BY A.cplateno
Can anybody tell what went wrong?
The "group by" clause must name every column selected, except those columns that are aggregate functions.
FYI an "aggregate" function is one that returns a single value for many rows, like sum(), count(), etc
a.cconduction needs to be in the group by clause.
When using a Group By clause, a column must either have an aggregate function (i.e. COUNT) or be defined in the group by.
A sample group by statement with multiple grouping:
SELECT column1_name, column2_name, aggregate_function(column_name3)
FROM table_name
WHERE column_name1 operator value
GROUP BY column_name1, column_name2;
You must include all fields that you mentioned in your select except the column that has aggregate function so in your case it would be:
GROUP BY
a.cplateno, a.cconduction,a.cname,a.cbatterymodel,a.dbattery,
a.DlastChange,a.nlastoilkm,a.naveragekmday,
a.dkmreading,a.dfranacq,a.dfranexp,a.nlimit,a.dreading
instead of
GROUP BY a.cplateno
Edit:
If you want only the a.cplateno then you don't include the rest of the fields except aggregate function and a.cplateno like:
SELECT A.cplateno
,CONVERT(varchar(2),month(MAX(B.dinsexp)))+'/'+CONVERT(varchar(2),day(MAX(B.dinsexp)))+'/'+CONVERT(varchar(4),year(MAX(B.dinsexp))) as dinsexp
,CONVERT(varchar(2),month(MAX(C.dregexp)))+'/'+CONVERT(varchar(2),day(MAX(C.dregexp)))+'/'+ CONVERT(varchar(4),year(MAX(C.dregexp))) as dregexp
FROM VEHICLEMASTR A
LEFT JOIN VEHICLEINSURANCE B
ON A.cplateno = B.cplateno
LEFT JOIN VREGISTRATION C
ON A.cplateno = C.cplateno
GROUP BY A.cplateno

Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I'm trying to select a bunch of patients with their unit and division and I want to group the result by unit name, but this code doesn't execute and gives the error as the topic of this question.
SELECT TOP (100) PERCENT
Pat.PatName AS Name,
srvDiv.sgMType AS Perkhidmatan,
Pat.PatMRank AS Pangkat,
Pat.PatMilitaryID AS [No# Tentera],
unt.untName AS Unit,
fct.pesStatusCode as StatusCode,
fct.pesSignedDate AS SignedDate
FROM dbo.FactPES AS fct INNER JOIN
dbo.DimPatient AS Pat ON fct.pesPatID = Pat.PatID LEFT OUTER JOIN
dbo.DimUnit AS unt ON fct.pesUnitID = unt.untID LEFT OUTER JOIN
dbo.DimServiceDiv AS srvDiv ON fct.pesServiceDivID = srvDiv.sgID
GROUP BY unt.untName
HAVING (deas.diDate BETWEEN
CONVERT(DATETIME, #FromDate, 102)
AND
CONVERT(DATETIME, #ToDate, 102))
I assume it's because unt.UntName is in my left join so I can't use it outside the join maybe ? I'm a bit confused because when I put it like this it works:
GROUP BY unt.untName, Pat.PatName, srvDiv.sgMType,
Pat.PatMRank, Pat.PatMilitaryID, unt.untName,
fct.pesStatusCode, fct.pesSignedDate
Any help is appreciated
First, please don't use TOP (100) PERCENT; it hurts even to read.
Second, your query contains no aggregate function, no SUM or COUNT for example. When you say you want to "group by unit name", I suspect you may simply want the results sorted by unit name. In that case, you want ORDER BY instead. (The advice from other to study what group by does is well taken.)
Finally, you might not need those CONVERT functions at the end, depending on your DBMS.
Whenever you use a GROUP BY - it should be present in the SELECT statement as a column. And if you do not want to contain it in a GROUP BY use it as an AGGREGATE column in SELECT.
So now in your case the second GROUP BY stated in your question will work.
Read this to understand more about GROUP BY