SUM ADD Different Table same ID - sql

I have no idea of how to resolve this..
SELECT c.NIF,
v.preu
FROM CLIENTS c
INNER JOIN RESERVES_VIATGES r
INNER JOIN VIATGES v
ON r.CODI_VIATGE = v.CODI
ON c.NIF = r.NIF_CLIENT
GROUP BY c.NIF, v.preu;
This query returns 2 column like:
NIF PRICE
111 200
222 600
111 100
I want to select the SUM of price that have the same NIF.
How Can I do it? Thanks

Use the SUM() aggregate function and remove v.preu from your GROUP BY clause.
SELECT c.NIF,
SUM(v.preu) preu
FROM CLIENTS c
INNER JOIN RESERVES_VIATGES r
ON c.NIF = r.NIF_CLIENT
INNER JOIN VIATGES v
ON r.CODI_VIATGE = v.CODI
GROUP BY c.NIF;

you can use SUM() aggregate function like
SELECT c.NIF, sum(v.preu) as Sum_price
FROM CLIENTS c
INNER JOIN RESERVES_VIATGES r
ON c.NIF = r.NIF_CLIENT
INNER JOIN VIATGES v
ON r.CODI_VIATGE = v.CODI
GROUP BY c.NIF;

Related

CALCULATE PERCENT BY DEVIDING AGREGATED VALUE ON TOTAL

I'm trying to write a query that aggregates a column by a category and then find a percent of that category from total categories
WITH USERS_ENERGY AS
(SELECT D.REGION_ID,E.YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,B.ELECTRICITY_TYPE_KEY,SUM(WEIGHT_FINAL) HH_BY_ELECTRICITY_TYPE
FROM
R_FACT_HOUSING_UNIT B
JOIN
RR_DIM_SAMPLE C ON B.SAMPLE_FORM_ID=C.SAMPLE_FORM_ID
JOIN
R_DIM_PLACES D ON C.FRAM_PLACE_ID=D.PLACE_ID
JOIN
R_DIM_YEAR E ON B.ROUND_YEAR=E.ID
JOIN
R_DIM_HOME_TYPE F ON F.HOME_TYPE_ID=B.HOME_TYPE_KEY
JOIN
R_DIM_OWNERSHIP_TYPE G ON G.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_KEY
WHERE B.ELECTRICITY_TYPE_KEY IN(8200002,8200001)
GROUP BY D.REGION_ID,E.YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,B.ELECTRICITY_TYPE_KEY),
ALL_HH AS
(
SELECT REGION_ID,YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,SUM(B.WEIGHT_FINAL) TOTAL_HH
FROM
R_FACT_HOUSING_UNIT B
JOIN
RR_DIM_SAMPLE C ON B.SAMPLE_FORM_ID=C.SAMPLE_FORM_ID
JOIN
R_DIM_PLACES D ON C.FRAM_PLACE_ID=D.PLACE_ID
JOIN
R_DIM_YEAR E ON B.ROUND_YEAR=E.ID
JOIN
R_DIM_HOME_TYPE F ON F.HOME_TYPE_ID=B.HOME_TYPE_KEY
JOIN
R_DIM_OWNERSHIP_TYPE G ON G.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_KEY
WHERE B.ELECTRICITY_TYPE_KEY IN(8200002,8200001)
GROUP BY REGION_ID,YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID
)
SELECT A."REGION_ID",A."YEAR_DESC",A."HOME_TYPE_ID",A."OWNERSHIP_TYPE_ID",A."ELECTRICITY_TYPE_KEY",A."HH_BY_ELECTRICITY_TYPE",TOTAL_HH FROM USERS_ENERGY A,ALL_HH B WHERE A.REGION_ID=B.REGION_ID AND A.YEAR_DESC=B.YEAR_DESC AND A.HOME_TYPE_ID=B.HOME_TYPE_ID AND A.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_ID
that was the view I created.
when I tried to test it gave me wrong results
this was my test
SELECT ELECTRICITY_TYPE_KEY,SUM(HH_BY_ELECTRICITY_TYPE),SUM(TOTAL_HH)FROM MASDAR_HEN_3_A_A T
GROUP BY ELECTRICITY_TYPE_KEY
ORDER BY ELECTRICITY_TYPE_KEY
the result was:
but it supposes to be:
so if you devide values on total and add them it supposes to give 100%
Your query is almost impossible to follow. Some helpful advice for your query-writing:
Always use MEANINGFUL table alases, such as y for dim_year. Arbitrary letters are hard to follow.
Always use proper, explicit, standard JOIN syntax. Never use commas in the FROM clause.
As for your view, I think you just need analytic functions. A simpler version (assuming I haven't make mistakes on the table aliases):
SELECT p.REGION_ID, y.YEAR_DESC, ht.HOME_TYPE_ID, ot.OWNERSHIP_TYPE_ID, hu.ELECTRICITY_TYPE_KEY,
SUM(WEIGHT_FINAL) as HH_BY_ELECTRICITY_TYPE
SUM(SUM(WEIGHT_FINAL)) OVER (REGION_ID,YEAR_DESC, HOME_TYPE_ID, OWNERSHIP_TYPE_ID) as TOTAL_HH
FROM R_FACT_HOUSING_UNIT hu JOIN
RR_DIM_SAMPLE
ON hu.SAMPLE_FORM_ID = s.SAMPLE_FORM_ID JOIN
R_DIM_PLACES p
ON s.FRAM_PLACE_ID= p.PLACE_ID JOIN
R_DIM_YEAR y
ON hu.ROUND_YEAR = y.ID JOIN
R_DIM_HOME_TYPE ht
ON ht.HOME_TYPE_ID = hu.HOME_TYPE_KEY JOIN
R_DIM_OWNERSHIP_TYPE ot
ON ot.OWNERSHIP_TYPE_ID= hu.OWNERSHIP_TYPE_KEY
WHERE hu.ELECTRICITY_TYPE_KEY IN (8200002, 8200001)
GROUP BY p.REGION_ID, y.YEAR_DESC, ht.HOME_TYPE_ID, ot.OWNERSHIP_TYPE_ID, hu.ELECTRICITY_TYPE_KEY;
Oracle provides a RATIO_TO_REPORT analytic function to compute % of total for you.
SELECT
d.region_id,
e.year_desc,
home_type_id,
ownership_type_id,
b.electricity_type_key,
SUM(weight_final) hh_by_electricity_type,
100*RATIO_TO_REPORT(SUM(weight_final) OVER ( PARTITION BY REGION_ID,YEAR_DESC, HOME_TYPE_ID, OWNERSHIP_TYPE_ID ) pct_of_total
FROM
r_fact_housing_unit b
JOIN rr_dim_sample c ON b.sample_form_id = c.sample_form_id
JOIN r_dim_places d ON c.fram_place_id = d.place_id
JOIN r_dim_year e ON b.round_year = e.id
JOIN r_dim_home_type f ON f.home_type_id = b.home_type_key
JOIN r_dim_ownership_type g ON g.ownership_type_id = b.ownership_type_key
WHERE
b.electricity_type_key IN (
8200002,
8200001
)
GROUP BY
d.region_id,
e.year_desc,
home_type_id,
ownership_type_id,
b.electricity_type_key;
Here is another example, using the Oracle data dictionary for input data, for readers who do not have data model to test with:
SELECT owner,
sum(bytes) total_bytes,
100*ratio_to_report(sum(bytes)) over () pct_of_total
FROM dba_segments
GROUP BY owner;

postgresql count distinct on differect condition

I'm stuck on an exercise where I need to count the total amount of unique visits to planets, but if the planet is the moon (maan), then it should be counted twice. Also the client number should be 121
select case
when objectnaam = 'Maan' then count(objectnaam)
else count(distinct objectnaam)
end as aantal_bezoeken
from klanten inner join deelnames on klanten.klantnr = deelnames.klantnr
inner join reizen on deelnames.reisnr = reizen.reisnr
inner join bezoeken on reizen.reisnr = bezoeken.reisnr
where klanten.klantnr = 121
group by objectnaam
And it gives me this result
aantal_bezoeken
1
4
1
1
but the result should be
aantal_bezoeken
7
I just need to add all these values together but I don't know how to,
or maybe there's a better more simple solution. It should be without subqueries
Try this:
select sum(aantal_bezoeken) as aantal_bezoeken from
(select case
when objectnaam = 'Maan' then count(objectnaam)
else count(distinct objectnaam)
end as aantal_bezoeken
from klanten inner join deelnames on klanten.klantnr = deelnames.klantnr
inner join reizen on deelnames.reisnr = reizen.reisnr
inner join bezoeken on reizen.reisnr = bezoeken.reisnr
where klanten.klantnr = 121
group by objectnaam) as a

MS Access (via VB.NET) - convert linked attribute tables to columns in output

I've searched, and found a lot of similar things, but not quite what I'm looking for.
I have what are essentially a bunch of linked tables with attributes and values.
xxBio table
xxBio_ID xxBio_LINK
1 100
2 101
xx table
xxBio_LINK xxAttr_LINK
100 1000
101 2000
xxAttr table
xxAttr_LINK xxAttrCat_1_LINK xxAttrCat_2_LINK
1000 null 550
2000 650 null
xxAttrCat_1 table
xxAttrCat_1_LINK xxAttrCat_1_Description xxAttrCat_1_Value
650 wumpus 20
xxAttrCat_2 table
xxAttrCat_2_LINK xxAttrCat_2_Description xxAttrCat_2_Value
550 frith 30
OUTPUT NEEDS TO BE:
xxBio_ID frith wumpus
1 30 null
2 null 20
I can easily see how to get the result set with columns like attribute_name1, attribute_value1, attribute_name2, attribute_value2, and so forth.
SELECT xxBio.ID, xxAttrCat_1.xxAttrCat_1_Description, xxAttrCat_1.xxAttrCat_1_Value, xxAttrCat_2.xxAttrCat_2_Description, xxAttrCat_2.xxAttrCat_2_Value
FROM ((
(xx INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK)
INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK
But that's not what we need. We need the attribute names to be column names.
How do we achieve this?
Update to question:
It turned out that we misunderstood the requirements, so we had to take a different route and did not get to try the answers. I appreciate the help.
Put the SQL in a string and execute from VBA. (Dynamic SQL?)
sql = "SELECT xxBio.ID, " & xxAttrCat_1.xxAttrCat_1_Description & ", " & ...
Consider using IIF() conditional statements:
SELECT xxBio.ID,
IIF(xxAttrCat_1.xxAttrCat_1_Description = 'wumpus',
xxAttrCat_1.xxAttrCat_1_Value, NULL) As [wumpus],
IIF(xxAttrCat_2.xxAttrCat_2_Description = 'frith',
xxAttrCat_2.xxAttrCat_2_Value, NULL) As [frith]
FROM (((xx
INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK)
INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK
If each ID can have multiple values along same descriptions and you need to sum or average all corresponding values, then turn query into conditional aggregation (known as pivoting). Below also uses table aliases, a, b, c1, c2 for brevity and organization.
SELECT b.ID,
SUM(IIF(c1.xxAttrCat_1_Description='wumpus', c1.xxAttrCat_1_Value, NULL)) As [wumpus],
SUM(IIF(c2.xxAttrCat_2_Description='frith', c2.xxAttrCat_2_Value, NULL)) As [frith]
FROM (((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK
GROUP BY b.ID
And if such descriptions can be many use MS Access SQL's crosstab query. But since you have two categories, run a crosstab on each and save them as stored queries or views. Then, join together:
--CATEGORY 1
TRANSFORM SUM(c1.xxAttrCat_1_Value) AS SumOfValue
SELECT b.ID,
FROM ((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK
GROUP BY b.ID
PIVOT c1.xxAttrCat_1_Description;
--CATEGORY 2
TRANSFORM SUM(c2.xxAttrCat_2_Value) AS SumOfValue
SELECT b.ID,
FROM ((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK
GROUP BY b.ID
PIVOT c2.xxAttrCat_2_Description;
--CROSSTAB QUERIES JOIN
SELECT c1.*, c2.*
FROM Categ1CrossTabQ c1
INNER JOIN Categ1CrossTabQ c2
ON c1.ID = c2.ID;
Please note: comments above with double dash are not allowed in an Access query and only one statement is allowed in saved query. Access has a limit of 255 columns per table/query, so pivoted values greater than 255 will err out unless you use IN clause. Finally, you cannot use crosstabs as subqueries. And crosstabs are strictly an MS Access command and not used in other DBMS's.

select columns from different tables with different data type columns

I want to know how to write a query, which selects specific columns(not common) from 2 different tables and combine them together.
I tried this, but didn't work:
SELECT ii.sequence
FROM Costs ii
WHERE ii.order_ID IN (SELECT book.order_ID
FROM BookInfo ci
WHERE ii.order_ID = ci.order_ID)
UNION
SELECT ft.released_title
FROM FinishedBook ft
WHERE ft.version IN (SELECT ii.iiversion
FROM Costs ii
WHERE ii.iiorder_ID IN (SELECT ci.order_ID
FROM BookInfo ci
WHERE ii.iiorder_ID = ci.order_ID))
ORDER BY sequence;
Isn't this a case of joining these tables and calling Distinct to avoid duplicates?
Try this:
select Distinct a.Sequence, b.RELEASED_TITLE
from IncludedIn a inner join FinishedTrack b
on a.OriginatesFrom = b.IIOriginatesFrom
Inner join CdInfo c on a.IIALBUM_ID = c.ALBUM_ID
Order By a.Sequence
For MSSQL Server, Use Join to get the result.
SELECT I.Sequence, F.Released_Title FROM FinishedTrack AS F
INNER JOIN IncludedIn AS I ON I.ORIGINATESFROM = F.IIORIGINATESFROM
INNER JOIN CdInfo AS A ON A.ALBUM_ID = I.IIALBUM_ID
ORDER BY I.Sequence DESC
You need to use a JOIN instead of a UNION:
SELECT ii.sequence, ft.released_title
FROM IncludedIn ii
INNER JOIN CdInfo ci ON ii.iialbumid = ci.album_id
INNER JOIN FinishedTrack ft on ft.originatesfrom = ii.iioriginatesfrom
ORDER BY ii.sequence;
This query might work for you
SELECT IncludedIn.SEQUENCE, FinishedTrack.RELEASED_TITLE
FROM FinishedTrack
INNER JOIN IncludedIn
ON FinishedTrack.ORIGINATESFROM=IncludedIn.IIORIGINATESFROM and
FinishedTrack.VERSION=IncludedIn.IIVERSION order by FinishedTrack.SEQUENCE;

select query in subquery giving Column is invalid in the select list because it is not contained error

I have following query which i want to get sum counts for my data
SELECT
TI.[text] as zone,
YEAR (ER.Inserted) as [Year],
SUM(CONVERT(INT,DRT.RDRT)) as RDRT,
SUM(CONVERT(INT,DRT.FACT)) as FACT ,
SUM(CONVERT(INT,DRT.ERU)) as ERU,
(
SELECT COUNT(ER1.ReportID)
FROM dbo.EW_Reports ER1
INNER JOIN dbo.EW_Report_InformationManagement ERI ON ER1.ReportID = ERI.ReportID
INNER JOIN EW_Report_Country ERC1 ON ER1.ReportID = ERC1.ReportID
INNER JOIN ApplicationDB.dbo.Country C1 ON ERC1.CountryID = C1.countryId
INNER JOIN ApplicationDB.dbo.Region R1 ON C1.regionId = R1.regionId
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE ERI.EmergencyAppeal IS NOT NULL
AND (YEAR ( ER1.Inserted) = YEAR ( ER.Inserted))
AND Z1.zoneId = Z.zoneId
) as emergencyAppeals
FROM EW_Reports ER
INNER JOIN EW_DisasterResponseTools DRT ON ER.ReportID = DRT.ReportID
INNER JOIN EW_Report_Country ERC ON ER.ReportID = ERC.ReportID
INNER JOIN ApplicationDB.dbo.Country C ON ERC.CountryID = c.countryId
INNER JOIN ApplicationDB.dbo.Region R ON c.regionId = R.regionId
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
INNER JOIN ApplicationDB.dbo.Translation T ON Z.translationId = T.translationId
INNER JOIN ApplicationDB.dbo.TranslationItem TI ON T.translationId = TI.translationId
INNER JOIN EW_lofDisasterTypes D ON ER.DisasterTypeID = D.TranslationID AND D.LanguageID = 1 AND TI.languageID = 1
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
GROUP BY TI.[text], YEAR (ER.Inserted)
But its giving following error
Column 'ApplicationDB.dbo.Zone.zoneId' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Please assist me how to resolve this error .
there are too many ApplicationDB.dbo.Zone.zoneId records in your table already
simple add ApplicationDB.dbo.Zone.zoneId in group by then problem will solved
Select ....
.....
GROUP BY TI.[text], YEAR (ER.Inserted) ,ApplicationDB.dbo.Zone.zoneId
For your question why u need to add ApplicationDB.dbo.Zone.zoneId in my group as i am using that in ur subquery, this is because u perform a outer condition in your subquery
SELECT
----
(
SELECT
-----
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE
----
AND Z1.zoneId = Z.zoneId
)
-----
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
------
note that you have a condition in different years
so your data flow may like this
ZoneID Years Record
1 2011 1000
1 2012 1000
same zone id contain different years, without proper grouping, sql got no way to group years column
it is showing the error because you have used this in sub query where condition
you need toadd ApplicationDB.dbo.Zone.zoneId in group by