Orale is returning an error in the group by using alias column.
SELECT
CONCAT( CONCAT( a.air_location, ' ,' ), a.air_code ) AS "Departs From",
CONCAT( CONCAT( ad.air_location, ' ,' ), ad.air_code ) AS "Arrives At",
MIN(f.fl_fare) AS "Minimun Fare"
FROM flight f
INNER JOIN airport a ON a.air_code = f.fl_dest
INNER JOIN airport ad ON ad.air_code = f.fl_orig
GROUP BY "Departs From", "Arrives At";
It is returning:
ORA-00904: "Arrives At": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 10 Column: 26
You can't use a column alias in the GROUP BY clause in Oracle - and positional parameters are not supported either. You need to repeat the expression, or use a subquery or cte. So:
select
ao.air_location || ' ,' || ao.air_code as departs_from,
ad.air_location || ' ,' || ad.air_code as arrives_at,
min(f.fl_fare) as minimun_fare
from flight f
inner join airport ad on ad.air_code = f.fl_dest
inner join airport ao on ao.air_code = f.fl_orig
group by
ao.air_location || ' ,' || ao.air_code
ad.air_location || ' ,' || ad.air_code
Other changes to your query:
changed table aliases to names that seem more meaningful to me (and I think you had the origin and destination inverted in the result)
used standard ANSI string concatenation operator || instead of CONCAT(), which Oracle supports
used column aliases that do not require quoting (without embedded spaces), because it makes the query easier to write - you can revert that change if you really want otherwise.
As a final thought: here is an alternative that uses a lateral join to generate the aliases:
select x.departs_from, x.arrives_at, min(f.fl_fare) as minimun_fare
from flight f
inner join airport ad on ad.air_code = f.fl_dest
inner join airport ao on ao.air_code = f.fl_orig
cross apply (
select
ao.air_location || ' ,' || ao.air_code as departs_from,
ad.air_location || ' ,' || ad.air_code as arrives_at
from dual
) x
group by x.departs_from, x.arrives_at
Wrap your CONCAT query up in a derived table, GROUP BY its result:
SELECT "Departs From", "Arrives At", MIN(fl_fare) as minimun_fare
FROM
(
SELECT
CONCAT( CONCAT( a.air_location, ' ,' ), a.air_code ) AS "Departs From",
CONCAT( CONCAT( ad.air_location, ' ,' ), ad.air_code ) AS "Arrives At",
f.fl_fare
FROM flight f
INNER JOIN airport a ON a.air_code = f.fl_dest
INNER JOIN airport ad ON ad.air_code = f.fl_orig
) dt
GROUP BY "Departs From", "Arrives At";
(The GROUP BY is evaluated before the SELECT list. So the column aliases can't be used in the GROUP BY since they don't yet exist.)
Related
I am getting an error in the below query.. can anyone help fixing this query
select c.CHANGE_NUMBER,
(select le.ENTRYVALUE from listentry le
where le.ENTRYID = c.CATEGORY)as CATEGORY ,
(
SELECT last_name || ',' || first_name || '(' || loginid || ')'
FROM agileuser
WHERE id = c.ORIGINATOR
) initiator,(
SELECT last_name || ',' || first_name || '(' || loginid || ')'
FROM agileuser
WHERE id = c.owner
) coordinator, w.state,
(SELECT description
FROM nodetable
WHERE id = w.state
) workflow_status , TO_CHAR(w.LOCAL_DATE,'DD-MON-YY HH24:MI:SS')local_date,
(select
(trunc(to_date(B.local_date, 'DD-MON-YY HH24:MI:SS') - to_date(w.local_date, 'DD-MON-YY HH24:MI:SS')))as timediff
FROM WORKFLOW_PROCESS w INNER JOIN WORKFLOW_PROCESS B ON B.order_by = (w.order_by + 1)
where w.change_id=B.Change_id and w.change_id=9946301 )--ORDER BY w.order_by ASC
from change c, WORKFLOW_PROCESS w
where w.change_id = c.id-- order by w.ORDER_BY)
and c.CHANGE_NUMBER='NPI001084'
order by w.ORDER_BY,local_date ASC
The trunc() query gives multiple records
select
(trunc(to_date(B.local_date, 'DD-MON-YY HH24:MI:SS') - to_date(w.local_date, 'DD-MON-YY HH24:MI:SS')))as timediff
FROM WORKFLOW_PROCESS w INNER JOIN WORKFLOW_PROCESS B ON B.order_by = (w.order_by + 1)
where w.change_id=B.Change_id and w.change_id=9946301 ORDER BY w.order_by ASC
hence not able to run along with this main query.
What a mess! You should really consider using SQL formatter or - if you can't for some reason - try to format code you write manually. This is unreadable.
Anyway: although subqueries look like a nice way out of your problems, generally - avoid them. Most of those can be rewritten so that you properly join tables involved.
If you choose to use them within the SELECT statement, you have to make sure that each of them returns a single value.
This returns two or more rows:
SELECT (TRUNC (
TO_DATE (b.local_date, 'DD-MON-YY HH24:MI:SS')
- TO_DATE (w.local_date, 'DD-MON-YY HH24:MI:SS')))
AS timediff
FROM workflow_process w
INNER JOIN workflow_process b ON b.order_by = (w.order_by + 1)
WHERE w.change_id = b.change_id
AND w.change_id = 9946301
How to fix it? I don't know, I don't have your tables and have no idea what you want. Simple options might be to:
select distinct timediff ...
or
select max(timediff) ...
or
select ...
where rownum = 1
or some other option, but - again, it depends on something we don't know.
Completely untested, and probably with some typos, also possibly joins that should be left joins, and maybe incorrect oracle syntax, but...
select c.CHANGE_NUMBER,
le.ENTRYVALUE as CATEGORY
orig.last_name || ',' || orig.first_name || '(' || orig.loginid || ')' as initiator,
own.last_name || ',' || own.first_name || '(' || own.loginid || ')' as coordinator,
w.state,
n.description as workflow_status,
TO_CHAR(w.LOCAL_DATE,'DD-MON-YY HH24:MI:SS')local_date,
trunc(to_date(B.local_date, 'DD-MON-YY HH24:MI:SS') - to_date(w.local_date, 'DD-MON-YY HH24:MI:SS')) as timediff
from change c
join WORKFLOW_PROCESS w on w.change_id = c.id
join listentry le on le.ENTRYID = c.CATEGORY
join agileuser as orig on orig.id = c.ORIGINATOR
join agileuser as own on own.id = c.owner
join nodetable as n on n.id = w.state
JOIN WORKFLOW_PROCESS B ON B.order_by = (w.order_by + 1)
where c.CHANGE_NUMBER='NPI001084'
order by w.ORDER_BY,local_date ASC
1.Main Code:
SELECT
iodv.organization_id,
iodv.organization_name,
mil.SUBINVENTORY_CODE subinventory_name,
mil.inventory_location_id locator_id,
mil.segment11 || '.' || mil.segment12 || '.' || mil.segment13 locator_name
FROM
inv_item_locations mil,
inv_organization_definitions_v iodv
WHERE
1 = 1
and iodv.organization_id = mil.organization_id
and iodv.Organization_Code = ':Organizations'
and mil.SUBINVENTORY_CODE = ':p_Subinventories'
Parameter p_SubInventories:
select
distinct
iil.Subinventory_code
from
inv_item_locations iil,
INV_ORG_PARAMETERS iop
where
1=1
and iil.ORGANIZATION_ID=iop.ORGANIZATION_ID
and iop.ORGANIZATION_CODE= :Organizations
Parameter for Organizations:
select distinct organization_code from inv_org_parameters
Unable to retrieve data with the above query in Data Model # Oracle BI Publisher......
LEFT JOIN here
SELECT
iodv.organization_id,
iodv.organization_name,
mil.SUBINVENTORY_CODE subinventory_name,
mil.inventory_location_id locator_id,
mil.segment11 || '.' || mil.segment12 || '.' || mil.segment13 locator_name
FROM
inv_item_locations mil
LEFT JOIN
inv_organization_definitions_v iodv
ON
iodv.organization_id = mil.organization_id
WHERE 1 = 1
AND iodv.Organization_Code = ':Organizations'
AND mil.SUBINVENTORY_CODE = ':p_Subinventories'
I would have thought the single apostrophe was problem, but maybe removing the inner join also helps.
It's worth noting the LEFT JOIN could be applied using using PL SQL Outer Join Operator (+). See adjustment to Ops main code below
SELECT
iodv.organization_id,
iodv.organization_name,
mil.SUBINVENTORY_CODE subinventory_name,
mil.inventory_location_id locator_id,
mil.segment11 || '.' || mil.segment12 || '.' || mil.segment13 locator_name
FROM
inv_item_locations mil,
inv_organization_definitions_v iodv
WHERE
1 = 1
and iodv.organization_id (+) = mil.organization_id ----
and iodv.Organization_Code = ':Organizations'
and mil.SUBINVENTORY_CODE = ':p_Subinventories'
I have two queries. The first -
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
which basically outputs - | message_date | message_text | message_by |
And the second query -
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
which outputs - | com_id | recipient_name | phone_number |
As you can tell from the queries, both tables have a "com_id" column. What I need is to make a single query that will merge the two queries above to get a single output, something like -
|message_date|message_text|message_by|recipient_name|phone_number|
How can I achieve that? I can't use UNION because of the different data types and different number of columns. I'll appreciate your help guys.
Not sure if the com_id will be equal or not, but in case they might not be then I suggest this:
select * -- list out the columns, I haven't bothered here
FROM (
SELECT MAX(com_id) as com_id FROM app.communications
UNION
SELECT MAX(cs2.com_id) FROM app.communication_sms cs2
) u
left join (
SELECT
com_id -- don't know which table this comes from
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
) s1 on u.com_id = s1.com_id
left join (
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
) s2 on u.com_id = s2.com_id
Note a small amount of repetition could be avoided by using CTEs
Is there a reason why you would need to union or join? In the context you are asking the question com_id should not matter.
Try something like this, ( this query is nothing special basically just merged the two together )
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communications, app.communication_sms cs
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
AND cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
First query: You want the last communication identified by MAX(c.com_id), but only in case it is an SMS (c.send_as_sms = TRUE). For this SMS you want the sender's name. This query results in one or zero rows depending on whether the last communication was an SMS.
Second query: You want the last SMSs for the last SMS communication this time identified by MAX(cs.com_id). This looks redundant. Why do you have a send_as_sms in communications when you see from the existence of matching communication_sms records that this is an SMS? You may want to think over this design. Anyway, from this you want to get the recipient's name plus some phone number.
How to combine the two queries is not evident. Do you really want the latest SMSs with the recipients' names, but only add the sender's name in case this last SMS is also the last communication? This doesn't seem likely. I guess you rather want either
the lastest communication in case its an SMS or
the latest SMS communication
for both the sender and recipient. Or can you have non-SMS communications with SMSs attatched?
Here is a query for the last SMS communication:
SELECT
c.creation_date AS message_date,
c.message AS message_text,
e.first_name || ' ' || coalesce(e.middle_name,'') || ' ' || e.last_name AS message_by,
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM (SELECT * FROM app.communication_sms ORDER BY com_id DESC FETCH FIRST ROW ONLY) cs
JOIN app.communications c ON c.com_id = cs.com_id
JOIN app.employees e ON c.message_from = e.emp_id
ORDER cs.first_name ASC;
I have the following SQL query and as we see in the screenshot, there are two repeating row with the same constr_id(2015) value but with different assigned_insurance_packages.
Query:
select
ac.constr_id,
AIP.NAME as ASSIGNED_INSURANCE_PACKAGES,
ac.code,ac.constr_name,
ac.offer_name,
ac.repay_freq,
ac.min_amt,
ac.max_amt,
ac.min_downpay_percent,
ac.max_downpay_percent,
ac.downpay_amount,
ac.min_term,
(select
listagg(AF.NAME, '; ') within group(order by ACF.CONSTR_ID)
from
CREDILOGIC.ACQ_CONSTR_FEE acf, CREDILOGIC.ACQ_FEE af
where
ACF.CONSTR_ID = AC.CONSTR_ID and AF.FEE_ID = ACF.FEE_ID) as CONSTRUCTION_FEES,
INS_COMPANY.SHORT_NAME,
(select listagg(x.DURATION_MIN || '-' || TO_CHAR(x.RATE_SHIFT, '90.99') || ',' || x.DURATION_MAX || '-' || TO_CHAR(x.RATE_SHIFT, '90.99'), '; ') within group (order by X.CONSTRUCTION_ID)
from credilogic.ACQ_CONSTRUCTION_BASERATE x
where X.CONSTRUCTION_ID = AC.CONSTR_ID) as RATE
from
CREDILOGIC.ACQ_CONSTRUCTION ac
left join
CREDILOGIC.ACQ_CONSTR_INSPACKAGE aci on ACI.CONSTR_ID = AC.CONSTR_ID
and ACI.DELETED_TSTAMP is null
left join
CREDILOGIC.ACQ_INSURANCE_PACKAGE aip on AIP.INSURANCE_PACKAGE_ID = ACI.INSURANCE_PACKAGE_ID
left join
credilogic.ath_party ins_company ON INS_COMPANY.PARTY_ID = aip.PARTY_ID
left join
credilogic.ACQ_CONSTRUCTION_DUEDATE acd on ac.constr_id = acd.constr_id
left join
credilogic.ACQ_APPLICATION acp on ac.constr_id = acp.construction_id
I am just going to create two additional columns like 0.3% insurance pack and 0.5% insurance pack to put ASSIGNED_INSURANCE_PACKAGES values into different columns like in the picture below
I am having issues with combining two columns into the one using mssql
table 1 format:
|| WJCPrefix || WJCNo ||
|| UK-R/SWJC/14/ || 1234 ||
|| UK-R/CUWJC/14/ || 2345 ||
|| UK-R/CUWJC/14/ || 3456 ||
|| UK-R/SWJC/14/ || 4567 ||
|| UK-R/CUWJC/14/ || 5678 ||
The desired out would be:
UK-R/CUWJC/14/3456
UK-R/CUWJC/14/5678
the sql statement i am using is:
SELECT tblWJCItem.AddedDescription, concat(tblWJC.WJCPrefix, tblWJC.WJCNo) AS OurRef
FROM tblWJC
INNER JOIN tblWJCItem ON tblWJC.WJCID = tblWJCItem.WJCID;
I've also used:
SELECT tblWJCItem.AddedDescription, tblWJC.WJCPrefix + '' + tblWJC.WJCNo AS OurRef
FROM tblWJC
INNER JOIN tblWJCItem ON tblWJC.WJCID = tblWJCItem.WJCID;
I can't seem to connect these two columns could anyone point out what I am doing wrong here?
Thanks
Your first query (Concat() function) should work if you are using SQL Server 2012 or later.
For other versions, you may need to Convert()/Cast() WJCNo to a string type
SELECT t2.AddedDescription,
t1.WJCPrefix + CONVERT(Varchar(10),t1.WJCNo) AS OurRef
FROM tblWJC t1
INNER JOIN tblWJCItem t2 ON t1.WJCID = t2.WJCID;
Your first query should be fine. But you might try:
SELECT tblWJCItem.AddedDescription, tblWJC.Prefix + cast(tblWJC.WJCNo as varchar(255)) AS OurRef
FROM tblWJC INNER JOIN
tblWJCItem
ON tblWJC.WJCID = tblWJCItem.WJCID;
You might get an error in the second version if WJCno is numeric rather than a string.
I think WJCNo is numeric or int field so Convert this field to Varchar first then concat:-
SELECT tblWJCItem.AddedDescription,
tblWJC.WJCPrefix + '' + CONVERT(Varchar(10),tblWJC.WJCNo) AS OurRef
FROM tblWJC
INNER JOIN tblWJCItem ON tblWJC.WJCID = tblWJCItem.WJCID;