Query error IN GROUP BY - sql

I want only one F_LATPRIMI, F_LONPRIMI from any I_ID_NAVE
select I_ID_NAVE ,F_LATPRIMI ,F_LONPRIMI
from(
select
distinct imo,[N_ident_seguenziale]
from
navi
inner join
[ESTERNALIZZAZIONE_FASCICOLINAVE]
ON
[ESTERNALIZZAZIONE_FASCICOLINAVE].[I_ID_NAVE]=navi.[N_ident_seguenziale]
) as tabimo
inner join
posizioni
on
posizioni.[I_ID_NAVE]=tabimo.[N_ident_seguenziale]
where
DATEDIFF(minute, D_TS,GETDATE() )<30
group by I_ID_NAVE
The error is
Msg 8120, Level 16, State 1, Line 3 Column 'posizioni.F_LATPRIMI' is
invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.

I think what you are looking for is not GROUP BY rather ROW_NUMBER() function like
select I_ID_NAVE,
F_LATPRIMI ,
F_LONPRIMI
from (
select
imo,[N_ident_seguenziale], I_ID_NAVE,
F_LATPRIMI ,F_LONPRIMI,
ROW_NUMBER() OVER(PARTITION BY I_ID_NAVE ORDER BY I_ID_NAVE) AS rn
from
navi inner join [ESTERNALIZZAZIONE_FASCICOLINAVE]
ON [ESTERNALIZZAZIONE_FASCICOLINAVE].[I_ID_NAVE] = navi.[N_ident_seguenziale]) tabimo
join posizioni p on p.[I_ID_NAVE] = tabimo.[N_ident_seguenziale]
where DATEDIFF(minute, D_TS,GETDATE() ) < 30
and rn = 1;

One should group by all the columns which is in the select clause...
select I_ID_NAVE ,F_LATPRIMI ,F_LONPRIMI
from(
select
distinct imo,[N_ident_seguenziale]
from
navi
inner join
[ESTERNALIZZAZIONE_FASCICOLINAVE]
ON
[ESTERNALIZZAZIONE_FASCICOLINAVE].[I_ID_NAVE]=navi.[N_ident_seguenziale]
) as tabimo
inner join
posizioni
on
posizioni.[I_ID_NAVE]=tabimo.[N_ident_seguenziale]
where
DATEDIFF(minute, D_TS,GETDATE() )<30
group by I_ID_NAVE,F_LATPRIMI ,F_LONPRIMI

in MsSql when using an Group By, all other columns need to be in an aggregate function (like MAX(), etc).
So maybe what you want is to delete the last row group by I_ID_NAVE.
What do you really want?
Please explain to us so we can help
If you "want the last F_LATPRIMI and F_LONPRIMI from anyI_ID_NAVE"
use the "Last"-Aggregate-function:
select I_ID_NAVE ,LAST(F_LATPRIMI) ,LAST(F_LONPRIMI)
from(
select
distinct imo,[N_ident_seguenziale]
from
navi
inner join
[ESTERNALIZZAZIONE_FASCICOLINAVE]
ON
[ESTERNALIZZAZIONE_FASCICOLINAVE].[I_ID_NAVE]=navi.[N_ident_seguenziale]
) as tabimo
inner join
posizioni
on
posizioni.[I_ID_NAVE]=tabimo.[N_ident_seguenziale]
where
DATEDIFF(minute, D_TS,GETDATE() )<30
group by I_ID_NAVE

Related

Syntax error to combine left join and select

I'm getting a syntax error at Left Join. So in trying to combine the two, i used the left join and the brackets. I'm not sure where the problem is:
SELECT DISTINCT a.order_id
FROM fact.outbound AS a
ORDER BY Rand()
LIMIT 5
LEFT JOIN (
SELECT
outbound.marketplace_name,
outbound.product_type,
outbound.mpid,
outbound.order_id,
outbound.sku,
pbdh.mpid,
pbdh.product_type,
pbdh.validated_exp_reach,
pbdh.ultimate_sales_rank_de,
pbdh.ultimate_sales_rank_fr,
(
pbdh.very_good_stock_count + good_stock_count + new_Stock_count
) as total_stock
FROM
fact.outbound AS outbound
LEFT JOIN reporting_layer.pricing_bi_data_historisation AS pbdh ON outbound.mpid = pbdh.mpid
AND trunc(outbound.ordered_date) = trunc(pbdh.importdate)
WHERE
outbound.ordered_date > '2022-01-01'
AND pbdh.importdate > '2022-01-01'
LIMIT
5
) AS b ON a.orderid = b.order_id
Error:
You have an error in your SQL syntax; it seems the error is around: 'LEFT JOIN ( SELECT outbound.marketplace_name, outbound.product_t' at line 9
What could be the reason?
Place the first limit logic into a separate subquery, and then join the two subqueries:
SELECT DISTINCT a.order_id
FROM
(
SELECT order_id
FROM fact.outbound
ORDER BY Rand()
LIMIT 5
) a
LEFT JOIN
(
SELECT
outbound.marketplace_name,
outbound.product_type,
outbound.mpid,
outbound.order_id,
outbound.sku,
pbdh.mpid,
pbdh.product_type,
pbdh.validated_exp_reach,
pbdh.ultimate_sales_rank_de,
pbdh.ultimate_sales_rank_fr,
(pbdh.very_good_stock_count +
good_stock_count + new_Stock_count) AS total_stock
FROM fact.outbound AS outbound
LEFT JOIN reporting_layer.pricing_bi_data_historisation AS pbdh
ON outbound.mpid = pbdh.mpid AND
TRUNC(outbound.ordered_date) = TRUNC(pbdh.importdate)
WHERE outbound.ordered_date > '2022-01-01' AND
pbdh.importdate > '2022-01-01'
-- there should be an ORDER BY clause here...
LIMIT 5
) AS b
ON a.orderid = b.order_id;
Note that the select clause of the b subquery can be reduced to just the order_id, as no values from this subquery are actually selected in the end.
You can skip the LEFT JOIN, since no b columns are selected. (And SELECT DISTINCT makes sure any duplicates are eliminated.)
SELECT DISTINCT order_id
FROM fact.outbound
ORDER BY Rand()
LIMIT 5

New SQL user - I'm trying to extract the latest record in my query. Accountant new to SQL

For every AbsenceBalance.AbsenceTypesUID I want to return the latest record AbsenceBalance.BalanceTime for each AbsenceBalance.EmployeeUID
I have tried select max but it only returns the most recent entry for the entire table and not by AbsenceBalance.AbsenceTypesUID or AbsenceBalance.EmployeeUID
This is my query
SELECT TOP (1000)
AbsenceBalance.[UID],
AbsenceBalance.BalanceTime,
AbsenceBalance.AbsenceTypesUID,
AbsenceBalance.Mins,
Employee.FullName,
Employee.FirstName,
Employee.LastName,
AbsenceBalance.EmployeeUID,
absencetypes.LongName
from [RiteqDB].[dbo].[AbsenceBalance]
LEFT JOIN [RiteqDB].[dbo].Employee on AbsenceBalance.EmployeeUID = Employee.UID
LEFT JOIN [RiteqDB].[dbo].AbsenceTypes on absencebalance.AbsenceTypesUID = absencetypes.UID
where AbsenceBalance.[UID] = (select max (AbsenceBalance.[UID]) from [RiteqDB].[dbo].[AbsenceBalance] where AbsenceBalance.AbsenceTypesUID = AbsenceBalance.AbsenceTypesUID)
--where Select Max(v) from (values (AbsenceBalance.BalanceTime)
order by FullName, AbsenceTypesUID
It sounds like you might need a group by link, then either use an inner select in a where (like you have) or use this with an inner join.
SELECT
Max(AbsenceBalance.[UID]),
AbsenceBalance.AbsenceTypesUID,
AbsenceBalance.EmployeeUID,
from [RiteqDB].[dbo].[AbsenceBalance]
GROUP BY AbsenceTypesUID, EmployeeUID
;with cte as (
SELECT TOP (1000) AB.[UID]
,AB.BalanceTime
,AB.AbsenceTypesUID
,AB.Mins
,E.FullName
,E.FirstName
,E.LastName
,AB.EmployeeUID
,AT.LongName
, ROW_NUMBER() OVER(PARTITION BY AB.[UID], AB.EmployeeUID order by AB.BalanceTime DESC) AS RUN
FROM [RiteqDB].[dbo].[AbsenceBalance] AB
LEFT JOIN [RiteqDB].[dbo].Employee E ON AB.EmployeeUID = E.UID
LEFT JOIN [RiteqDB].[dbo].AbsenceTypes AT ON AB.AbsenceTypesUID = AT.UID
)
select * from cte
where RUN = 1
In your where condition your comparing with itself that might be the issue.
select max (AbsenceBalance.[UID]) from [RiteqDB].[dbo].[AbsenceBalance]
where AbsenceBalance.AbsenceTypesUID = AbsenceBalance.AbsenceTypesUID
following is wrong
AbsenceBalance.AbsenceTypesUID = AbsenceBalance.AbsenceTypesUID

How to get records with distinct column value from result set in oracle?

could you please help me on the below query?
Using the query
SELECT LineGernal.Id, LineGernal.Description, LineGernal.SSMS, BaseAddOns.Id
from LineGernal Inner Join
BaseAddOns
on LineGernal.Id=BaseAddOns.ParentLineGernalID
Output-
Result Needed-
Thanks
Rajendra
You can use group by and min as follows:
SELECT LineGernal.Id, LineGernal.Description, LineGernal.SSMS, min(BaseAddOns.Id) as id
from LineGernal Inner Join
BaseAddOns
on LineGernal.Id=BaseAddOns.ParentLineGernalID
GROUO BY LineGernal.Id, LineGernal.Description, LineGernal.SSMS
I would recommend pre-aggregation in a subquery:
select li.id as lineGeneralId, lg.description, lg.ssms, bao.id as BaseAddOnsId
from LineGernal lg
inner join (
select ParentLineGernalID, min(id) as id
from BaseAddOns
group by ParentLineGernalID,
) bao on lg.id = bao.ParentLineGernalID

ORDER in CTE lost after GROUP BY

I have the following SQL
WITH tally AS (
SELECT results.answer,
results.poll_id,
count(1) AS votes
FROM (
SELECT pr.poll_id,
unnest(pr.response) AS answer
FROM poll_responses pr
LEFT JOIN polls p ON pr.poll_id = p.id
LEFT JOIN poll_collections pc ON pc.id = p.poll_collection_id
WHERE pc.id = ${pollCollectionId}
) AS results
GROUP BY results.answer, results.poll_id
),
all_choices AS (SELECT unnest(pls.choices) AS choice,
pls.id AS poll_id
FROM poll_collections pcol
INNER JOIN polls pls
ON pcol.id = pls.poll_collection_id
WHERE pcol.id = ${pollCollectionId}),
unvoted_tally AS (SELECT ac.choice AS answer,
ac.poll_id,
0 AS total
FROM all_choices ac
LEFT JOIN tally t ON t.answer = ac.choice
WHERE t.answer IS NULL),
final_tally AS (SELECT *
FROM tally
UNION
ALL
SELECT *
FROM unvoted_tally),
sorted_tally AS (
SELECT ft.*
FROM final_tally ft
ORDER BY array_position(array(SELECT choice FROM all_choices), ft.answer)
)
SELECT json_agg(poll_results.polls) AS polls
FROM (
SELECT json_array_elements(json_agg(results)) -> 'poll' AS polls
FROM (
SELECT json_build_object(
'id', st.poll_id,
'question', pls.question,
'choice-type', pls.choice_type,
'results',
json_agg(json_build_object('choice', st.answer, 'votes', st.votes)),
'chosen', pr.response
) AS poll
FROM sorted_tally st
LEFT JOIN polls pls
ON
pls.id = st.poll_id
LEFT JOIN poll_responses pr
ON
pr.poll_id = st.poll_id AND
pr.email = ${email}
GROUP BY st.poll_id, pls.choice_type, pr.response, pls.question
) AS results)
AS poll_results;
I have a poll_responses table which store the user responses of a poll. I want to order the responses in exactly the same order they are stored in the polls table - as an array e.g., {Yes, No, Maybe}.
I applied the ORDER BY array_position(array(SELECT choice FROM all_choices), ft.answer) in the sorted_tally CTE.
However, in the file SELECT after applying GROUP BY the order is lost.
Is there a way to preserve the order of the choices?
Also, are there any optimizations applicable?
Much appreciated!
In json_build_object or json_agg you can set ORDER BY clause. First, have the last CTE SELECT needed order expression as a new column, then run in outermost query:
CTE
...
sorted_tally AS (
SELECT ft.votes
, ft.poll_id
, ft.answer
, array_position(array(SELECT choice FROM all_choices),
ft.answer) AS choice_order
FROM final_tally ft
ORDER BY
)
Outermost Query
...
json_build_object(
'id', st.poll_id,
'question', pls.question,
'choice-type', pls.choice_type,
'results', json_agg(json_build_object('choice', st.answer,
'votes', st.votes)
ORDER BY st.choice_order),
'chosen', pr.response
) AS poll
ORDER BY in a CTE doesn't really matter. It may work, but SQL Server is free to re-order the rows unless you specify ORDER BY in the outermost query to order all the results.

Why do I get ORA-00907 in my SQL query?

I have this SQL query which a partner has done for a little project at university (this is the first time we use SQL), but we get the ora-00907 error and both of us don't know why.
I have checked the parenthesis and they seem to be ok, so the problem must be another.
select
persona.nombre,
anyo,
t2.total
from persona join
(
select
t1.idPersona,
count(produccion.anyo) as total,
anyo
from
(
select *
from produccion
join pelicula
on produccion.id = pelicula.id
) as pel
join
(
select *
from participa
where idPapel = 8
) as t1
on t1.idProduccion = pel.id
)
group by t1.idPersona
) as t2
on persona.id = t2.idPersona
where t2.total > 2
order by t2.total desc;
You are selecting * and doing group by on one column which is creating problem. Either you select only respective column under group by condition OR you remove group by.
select *
from (produccion join pelicula on produccion.id=pelicula.id) as pel
join
(select *
from participa
where idPapel=8) as t1
on t1.idProduccion=pel.id)
group by t1.idPersona
Above code section is unallowed use of group by.
If group by is so much needed, i would suggest you to use it later on in the end. Another option is to use analytical function and filter out rest un-wanted records in upper nesting of query which you already have.
You have lots of nested views, which makes your query rather hard to debug. You have lots of brackets, which need to match.
Anyway this is wrong: select t1.idPersona, count(produccion.anyo) as total, anyo. You'll need to include anyo in the GROUP BY clause, which will probably change the result set you want.
select persona.nombre,
t2.anyo,
t2.total
from persona join
(select t1.idPersona,
count(produccion.anyo) as total,
anyo
from (select *
from produccion
join pelicula
on produccion.id=pelicula.id) pel
join
(select *
from participa
where idPapel=8) t1
on t1.idProduccion=pel.id
group by t1.idPersona, t1.anyo) t2
on persona.id=t2.idPersona
where t2.total>2
order by t2.total desc;
I think your query can be simplified/corrected like this:
select persona.nombre,
anyo,
t2.total
from persona
join (
select par.idPersona,
count(produccion.anyo) as total,
anyo
from produccion
join pelicula
on produccion.id = pelicula.id
left join participa par
on par.idProduccion = pelicula.id -- or produccion.id,
-- this was also an error in the original query,
-- since the subquery selected both
and par.idPapel = 8
group by t1.idPersona
, anyo -- Was missing, but it also doesn't make sense, as this is what you count, so you'll just get 1's here. What do you want with this?
) as t2
on persona.id = t2.idPersona
where t2.total > 2
order by t2.total desc;