SQL group by each tables and join them - sql

select home2012.region_name, avg(home2012.per_price), avg(home2019.per_price)
from home2012 left join
(select region_name, avg(per_price) from home2019 group by region_name)
on home2012.region_name = home2019.region_name
group by region_name;
I want to group by region_name each table(home2012, home2019) and left join them by same region_name(after group by).
But it occurs error.

Make two subselects and join them
SELECT
t2012.region_name, t2012.avgprice2012, t2019.avgprice2019
FROM
(SELECT
home2012.region_name, AVG(home2012.per_price) avgprice2012
FROM
home2012
GROUP BY region_name) AS t2012
LEFT JOIN
(SELECT
region_name, AVG(per_price) avgprice2019
FROM
home2019
GROUP BY region_name) AS t2019 ON t2012.region_name = t2019.region_name
;

select
home2012.region_name,
avg(home2012.per_price),
avg(home2019.per_price)
from
home2012
left join (select region_name, avg(per_price) from home2019 group by
region_name) on home2012.region_name = home2019.region_name
group by region_name;
what is the use of joining as mentioned above? does it make any difference rather than increasing one step workload on server.
select
home2012.region_name,
avg(home2012.per_price),
avg(home2019.per_price)
from
home2012
left join home2019 on home2012.region_name = home2019.region_name
group by region_name;

SELECT
name,
AVG("2012") as "2012",
AVG("2018") as "2018"
FROM
(
SELECT
'region' AS name,
1 AS "2012",
NULL AS "2018" // put column as null
FROM
dual
UNION
SELECT
'region' AS name,
NULL AS "2012", // put column as null
avg(3) AS "2018"
FROM
dual
group by 1
)
GROUP BY
name
am not sure about your requirement, try something like this.

Related

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

Unable to convert this legacy SQL into Standard SQL in Google BigQuery

I am not able to validate this legacy sql into standard bigquery sql as I don't know what else is required to change here(This query fails during validation if I choose standard SQL as big query dialect):
SELECT
lineitem.*,
proposal_lineitem.*,
porder.*,
company.*,
product.*,
proposal.*,
trafficker.name,
salesperson.name,
rate_card.*
FROM (
SELECT
*
FROM
dfp_data.dfp_order_lineitem
WHERE
DATE(end_datetime) >= DATE(DATE_ADD(CURRENT_TIMESTAMP(), -1, 'YEAR'))
OR end_datetime IS NULL ) lineitem
JOIN (
SELECT
*
FROM
dfp_data.dfp_order) porder
ON
lineitem.order_id = porder.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_proposal_lineitem) proposal_lineitem
ON
lineitem.id = proposal_lineitem.dfp_lineitem_id
JOIN (
SELECT
*
FROM
dfp_data.dfp_company) company
ON
porder.advertiser_id = company.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_product) product
ON
proposal_lineitem.product_id=product.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_proposal) proposal
ON
proposal_lineitem.proposal_id=proposal.id
LEFT JOIN (
SELECT
*
FROM
adpoint_data.dfp_rate_card) rate_card
ON
proposal_lineitem.ratecard_id=rate_card.id
LEFT JOIN (
SELECT
id,
name
FROM
dfp_data.dfp_user) trafficker
ON
porder.trafficker_id =trafficker.id
LEFT JOIN (
SELECT
id,
name
FROM
dfp_data.dfp_user) salesperson
ON
porder. salesperson_id =salesperson.id
Most likely the error you are getting is something like below
Duplicate column names in the result are not supported. Found duplicate(s): name
Legacy SQL adjust trafficker.name and salesperson.name in your SELECT statement into respectively trafficker_name and salesperson_name thus effectively eliminating column names duplication
Standard SQL behaves differently and treat both those columns as named name thus producing duplication case. To avoid it - you just need to provide aliases as in example below
SELECT
lineitem.*,
proposal_lineitem.*,
porder.*,
company.*,
product.*,
proposal.*,
trafficker.name AS trafficker_name,
salesperson.name AS salesperson_name,
rate_card.*
FROM ( ...
You can easily check above explained using below simplified/dummy queries
#legacySQL
SELECT
porder.*,
trafficker.name,
salesperson.name
FROM (
SELECT 1 order_id, 'abc' order_name, 1 trafficker_id, 2 salesperson_id
) porder
LEFT JOIN (SELECT 1 id, 'trafficker' name) trafficker
ON porder.trafficker_id =trafficker.id
LEFT JOIN (SELECT 2 id, 'salesperson' name ) salesperson
ON porder. salesperson_id =salesperson.id
and
#standardSQL
SELECT
porder.*,
trafficker.name AS trafficker_name,
salesperson.name AS salesperson_name
FROM (
SELECT 1 order_id, 'abc' order_name, 1 trafficker_id, 2 salesperson_id
) porder
LEFT JOIN (SELECT 1 id, 'trafficker' name) trafficker
ON porder.trafficker_id =trafficker.id
LEFT JOIN (SELECT 2 id, 'salesperson' name ) salesperson
ON porder. salesperson_id =salesperson.id
Note: if you have more duplicate names - you need to alias all of them too

Query error IN GROUP BY

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

How to use multiple count and where condition sql server 2008?

I have this two query
1.
select CL_Clients.cl_id,CL_Clients].cl_name,COUNT(*) AS number_of_orders
from CL_Clients,CLOI_ClientOrderItems
where CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id
2.
select CL_Clients.cl_id,count(cloi_current_status) as dis
from CLOI_ClientOrderItems,CL_Clients
where cloi_current_status]='12'
and CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id,CLOI_ClientOrderItems.cloi_current_status
i have this column i need to put count function and where condition
[cloi_current_status]
166
30
30
30
150
150
150
150
150
150
150
Quite simple, you just encapsulate the queries and give their result sets an alias and then do a JOIN between their aliases on the column that is common. (In the query below I assume you'll be joining by client id)
SELECT *
FROM (
SELECT CL_Clients.cl_id,
CL_Clients].cl_name,
COUNT(*) AS number_of_orders
FROM CL_Clients,
CLOI_ClientOrderItems
WHERE CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id
) A
INNER JOIN (
SELECT CL_Clients.cl_id,
count(cloi_current_status) AS dis
FROM CLOI_ClientOrderItems,
CL_Clients
WHERE cloi_current_status] = '12'
AND CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id,
CLOI_ClientOrderItems.cloi_current_status
) B
ON A.cl_id = B.cl_id
WHERE ...
GROUP BY ...
This will be treated as a separate result set, so you can also filter results with a WHERE or just a GROUP BY, just like in a normal SELECT.
UPDATE:
To answer the question in your comments, when you join two tables that have a column with the same value and use
SELECT * FROM A INNER JOIN B the * will show all columns returned by the join, meaning all columns from A and all columns from B, this is why you have duplicate columns.
If you want to filter the columns returned you can specifiy which columns you want returned. So, in your case, the top SELECT * can be replaced with
SELECT A.cl_id, A.cl_name, A.number_of_orders, B.dis so, your query becomes:
SELECT A.cl_id, A.cl_name, A.number_of_orders, B.dis
FROM (
SELECT CL_Clients.cl_id,
CL_Clients].cl_name,
COUNT(*) AS number_of_orders
FROM CL_Clients,
CLOI_ClientOrderItems
WHERE CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id
) A
INNER JOIN (
SELECT CL_Clients.cl_id,
count(cloi_current_status) AS dis
FROM CLOI_ClientOrderItems,
CL_Clients
WHERE cloi_current_status] = '12'
AND CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id,
CLOI_ClientOrderItems.cloi_current_status
) B
ON A.cl_id = B.cl_id
UPDATE #2:
For your last question, you need to GROUP BY at the end of the big query and use a HAVING condtion, like this:
GROUP BY A.cl_id, A.cl_name, A.number_of_orders, B.dis
HAVING COUNT(cloi_current_status) > 100
All depends on what data you are trying to get, but you can go about it like this.
SELECT Column_x, Column_y, etc..
FROM ClL_Clients a
JOIN (select CL_Clients.cl_id,CL_Clients].cl_name,COUNT(*) AS number_of_orders
from CL_Clients,CLOI_ClientOrderItems
where CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id) b
on a.cl_id = b.cl_id
JOIN (select CL_Clients.cl_id,count(cloi_current_status) as dis
from CLOI_ClientOrderItems,CL_Clients
where cloi_current_status]='12'
and CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id,CLOI_ClientOrderItems.cloi_current_status) c
on a.cl_id = c.cl_id
Group by BLAH BLAH
Hope this gets you in the right direction.

Produce result table trom multiple tables

SQL Server 2008 R2
I have 3 tables contained data for 3 different types of events
Type1, Type2, Type3 with two columns:
DatePoint ValuePoint
I want to produce result table which would look like that:
DatePoint TotalType1 TotalType2 TotalType3
I've started from that
SELECT [DatePoint]
,SUM(ValuePoint) as TotalType1
FROM [dbo].[Type1]
GROUP BY [DatePoint]
ORDER BY [DatePoint]
SELECT [DatePoint]
,SUM(ValuePoint) as TotalType2
FROM [dbo].[Type2]
GROUP BY [DatePoint]
ORDER BY [DatePoint]
SELECT [DatePoint]
,SUM(ValuePoint) as TotalType3
FROM [dbo].[Type3]
GROUP BY [DatePoint]
ORDER BY [DatePoint]
So I have three result but I need to produce one (Date TotalType1 TotalType2 TotalType3), what I need to do next achieve my goal?
UPDATE
Forgot to mention that DatePoint which is exists in one type may or may not exist in another
Here's my take. I assume that you don't have the same datetime values in every table (certainly, the stuff I get to work with is never so consistant). There should be an easier way to do this, but once you're past two outer joins things can get pretty tricky.
SELECT
dp.DatePoint
,isnull(t1.TotalType1, 0) TotalType1
,isnull(t2.TotalType2, 0) TotalType2
,isnull(t3.TotalType3, 0) TotalType3
from (-- Without "ALL", UNION will filter out duplicates
select DatePoint
from Type1
union select DatePoint
from Type2
union select DatePoint
from Type3) dp
left outer join (select DatePoint, sum(ValuePoint) TotalType1
from Type1
group by DatePoint) t1
on t1.DatePoint = db.DatePoint
left outer join (select DatePoint, sum(ValuePoint) TotalType2
from Type2
group by DatePoint) t2
on t2.DatePoint = db.DatePoint
left outer join (select DatePoint, sum(ValuePoint) TotalType3
from Type3
group by DatePoint) t3
on t3.DatePoint = db.DatePoint
order by dp.DatePoint
Suppose some distinct could help, but the general idea should be the following:
SELECT
t.[DatePoint],
SUM(t1.ValuePoint) as TotalType1,
SUM(t2.ValuePoint) as TotalType2,
SUM(t3.ValuePoint) as TotalType3
FROM
(
SELECT [DatePoint] FROM [dbo].[Type1]
UNION
SELECT [DatePoint] FROM [dbo].[Type2]
UNION
SELECT [DatePoint] FROM [dbo].[Type3]
) as t
LEFT JOIN
[dbo].[Type1] t1
ON
t1.[DatePoint] = t.[DatePoint]
LEFT JOIN
[dbo].[Type2] t2
ON
t2.[DatePoint] = t.[DatePoint]
LEFT JOIN
[dbo].[Type3] t3
ON
t3.[DatePoint] = t.[DatePoint]
GROUP BY
t.[DatePoint]
ORDER BY
t.[DatePoint]
To avoid all of the JOINs:
SELECT
SQ.DatePoint,
SUM(CASE WHEN SQ.type = 1 THEN SQ.ValuePoint ELSE 0 END) AS TotalType1,
SUM(CASE WHEN SQ.type = 2 THEN SQ.ValuePoint ELSE 0 END) AS TotalType2,
SUM(CASE WHEN SQ.type = 3 THEN SQ.ValuePoint ELSE 0 END) AS TotalType3
FROM (
SELECT
1 AS type,
DatePoint,
ValuePoint
FROM
dbo.Type1
UNION ALL
SELECT
2 AS type,
DatePoint,
ValuePoint
FROM
dbo.Type2
UNION ALL
SELECT
3 AS type,
DatePoint,
ValuePoint
FROM
dbo.Type3
) AS SQ
GROUP BY
DatePoint
ORDER BY
DatePoint
From the little information provided though, it seems like there are some flaws in the database design, which is probably part of the reason that querying the data is so difficult.