Add a field in table/view - sql

I want to calculate average values in a sql table/View by taking average of multiple values and want to group by another column.
For example in the attached excel sheet, I want to calculate average density from SG (Calc) field when Block ID is same.
+-----------------------------------+-----------+--------------+
| BlockID | SG (Calc) | Ave. Density |
+-----------------------------------+-----------+--------------+
| SESS_5835_01_OXD_SAP_AL01 | 1.86 | |
| SESS_5835_01_OXD_SAP_AL01 | 1.71 | |
| SESS_5835_01_OXD_SAP_MG04 | 2.08 | |
| SESS_5835_01_OXD_SAP_MG04 | 2.14 | |
| KCD_5897.5_01_OXD_TRA_VG02 | 2.74 | |
| KCD_5897.5_01_OXD_TRA_VG02 | 2.74 | |
| KCD_5897.5_01_OXD_TRA_VG02 | 2.51 | |
| KCD_5895_01_OXD_TRA_MG06 | 3.19 | |
| KCD_5895_01_OXD_TRA_MG06 | 3.02 | |
| SESS_58932.5_01_OXD_TRA_MG05 | 2.24 | |
| SESS_58932.5_01_OXD_TRA_MG05 | 2.27 | |
+-----------------------------------+-----------+--------------+

this will work:
select a.*,avg(SG(Calc)) from table_name a group by a.BlockID;

Are you looking for window functions?
select a.*, avg(SG) over (partition by blockid) as avg_block_density
from t a ;

Related

How to calculate the std of the previous 10 values over the time of a measures on MDX

I have to calculate the standard deviation of the 10 previous value of a measure X over the date hierarchy:
Something like that:
+------------+---------+---------+
| Date | X | std10d |
+------------+---------+---------+
| 24/04/2019 | 238985 | |
| 25/04/2019 | 61567 | |
| 26/04/2019 | -37350 | |
| 27/04/2019 | 27482 | |
| 28/04/2019 | 65499 | |
| 29/04/2019 | 3373 | |
| 30/04/2019 | 88660 | |
| 01/05/2019 | 22094 | |
| 02/05/2019 | 99731 | |
| 03/05/2019 | -4878 | |
| 04/05/2019 | -100024 | 77268 |
| 05/05/2019 | -54204 | 60966 |
| 06/05/2019 | -9833 | 63679 |
+------------+---------+---------+
I khow that the MDX formula should be like that :
stdev
(
[00_Time].[0_dateHierarchy].PrevMember.Lag(9) :
[00_Temps].[0_dateHierarcy].PrevMember,
[Measures].[X]
)
But I don't know what condition add to prevent the calculation of the first 10 value of std10d.
The expression [00_Time].[0_dateHierarchy].PrevMember.Lag(9).name for first 9 members will return null.Just check that null
Case
[Product].[Subcategory].currentmember.lag(9).name =null
then
null
else
stdev
(
[00_Time].[0_dateHierarchy].PrevMember.Lag(9) :
[00_Temps].[0_dateHierarcy].PrevMember,
[Measures].[X]
)
end

SQL subcategory total is not properly placed at the end of every parent category

I am having trouble in SQl query,The query result should be like this
+------------+------------+-----+------+-------+--+--+--+
| District | Tehsil | yes | no | Total | | | |
+------------+------------+-----+------+-------+--+--+--+
| ABBOTTABAD | ABBOTTABAD | 377 | 5927 | 6304 | | | |
| ABBOTTABAD | HAVELIAN | 112 | 2276 | 2388 | | | |
| ABBOTTABAD | Overall | 489 | 8203 | 8692 | | | |
| CHARSADDA | CHARSADDA | 289 | 3762 | 4051 | | | |
| CHARSADDA | SHABQADAR | 121 | 1376 | 1497 | | | |
| CHARSADDA | TANGI | 94 | 1703 | 1797 | | | |
| CHARSADDA | Overall | 504 | 6841 | 7345 | | | |
+------------+------------+-----+------+-------+--+--+--+
The overall total should be should be shown at the end of every parent category but now it is showing like this
+------------+------------+-----+------+-------+--+--+--+
| District | Tehsil | yes | no | Total | | | |
+------------+------------+-----+------+-------+--+--+--+
| ABBOTTABAD | ABBOTTABAD | 377 | 5927 | 6304 | | | |
| ABBOTTABAD | HAVELIAN | 112 | 2276 | 2388 | | | |
| ABBOTTABAD | Overall | 489 | 8203 | 8692 | | | |
| CHARSADDA | CHARSADDA | 289 | 3762 | 4051 | | | |
| CHARSADDA | Overall | 504 | 6841 | 7345 | | | |
| CHARSADDA | SHABQADAR | 121 | 1376 | 1497 | | | |
| CHARSADDA | TANGI | 94 | 1703 | 1797 | | | |
+------------+------------+-----+------+-------+--+--+--+
My query is sorting second column with respect to first column although order by query is applied on my first column. This is my query
select District as 'District', tName as 'tehsil',[1] as 'yes',[0] as 'no',ISNULL([1]+[0], 0) as "Total" from
(
select d.Name as 'District',
case when grouping (t.Name)=1 then 'Overall' else t.Name end as tName,
BoundaryWallAvailable,
count(*) as total from School s
INNER JOIN SchoolIndicator i ON (i.refSchoolID=s.SchoolID)
INNER JOIN Tehsil t ON (t.TehsilID=s.refTehsilID)
INNER JOIN district d ON (d.DistrictID=t.refDistrictID)
group by
GROUPING sets((d.Name, BoundaryWallAvailable), (d.Name,t.Name, BoundaryWallAvailable))
) B
PIVOT
(
max(total) for BoundaryWallAvailable in ([1],[0])
) as Pvt
order by District
P.S: BoundaryWall is one column through pivoting i am breaking it into Yes and No Column

Outer Join multible tables keeping all rows in common colums

I'm quite new to SQL - hope you can help:
I have several tables that all have 3 columns in common: ObjNo, Date(year-month), Product.
Each table has 1 other column, that represents an economic value (sales, count, netsales, plan ..)
I need to join all tables on the 3 common columns giving. The outcome must have one row for each existing combination of the 3 common columns. Not every combination exists in every table.
If I do full outer joins, I get ObjNo, Date, etc. for each table, but only need them once.
How can I achieve this?
+--------------+-------+--------+---------+-----------+
| tblCount | | | | |
+--------------+-------+--------+---------+-----------+
| | ObjNo | Date | Product | count |
| | 1 | 201601 | Snacks | 22 |
| | 2 | 201602 | Coffee | 23 |
| | 4 | 201605 | Tea | 30 |
| | | | | |
| tblSalesPlan | | | | |
| | ObjNo | Date | Product | salesplan |
| | 1 | 201601 | Beer | 2000 |
| | 2 | 201602 | Sancks | 2000 |
| | 5 | 201605 | Tea | 2000 |
| | | | | |
| | | | | |
| tblSales | | | | |
| | ObjNo | Date | Product | Sales |
| | 1 | 201601 | Beer | 1000 |
| | 2 | 201602 | Coffee | 2000 |
| | 3 | 201603 | Tea | 3000 |
+--------------+-------+--------+---------+-----------+
Thx
Devon
It sounds like you're using SELECT * FROM... which is giving you every field from every table. You probably only want to get the values from one table, so you should be explicit about which fields you want to include in the results.
If you're not sure which table is going to have a record for each case (i.e. there is not guaranteed to be a record in any particular table) you can use the COALESCE function to get the first non-null value in each case.
SELECT COALESCE(tbl1.ObjNo, tbl2.ObjNo, tbl3.ObjNo) AS ObjNo, ....
tbl1.Sales, tbl2.Count, tbl3.Netsales

MSAccess Query: Generate two fields

I have a MS Access view generating this result:
+-------+------------+-------+---------+--------+-------+
| Id | Date | Kind | Initial | Final | Total |
+-------+------------+-------+---------+--------+-------+
| 334AB | 01/04/2017 | Red | 199725 | 199789 | 64 |
| 334AB | 01/04/2017 | Green | 199789 | 199799 | 10 |
| 107AE | 01/04/2017 | Red | 73978 | 74074 | 96 |
| 107AE | 02/04/2017 | Green | 74074 | 74248 | 174 |
+-------+------------+-------+---------+--------+-------+
Generated with:
Group by ID, Date and Kind
Initial: Min(startKm)
Final: Max(endKm)
Total: Sum(Distance)
This is the query:
SELECT street.Id, street.Date, IIf(IsNull([agev]), Kind, Min(street.Initial) AS Iniziali, Max(street.Final) AS Finali, Sum(street.Distance) AS Total
FROM street
GROUP BY street.Id, street.Date, Kind
ORDER BY street.Date;
What I need is this result:
+-------+------------+---------+--------+----------+------------+-------+
| Id | Date | Initial | Final | TotalRed | TotalGreen | Total |
+-------+------------+---------+--------+----------+------------+-------+
| 334AB | 01/04/2017 | 199725 | 199799 | 64 | 10 | 74 |
| 107AE | 01/04/2017 | 73978 | 74074 | 96 | 0 | 96 |
| 107AE | 02/04/2017 | 74074 | 74248 | 0 | 174 | 174 |
+-------+------------+---------+--------+----------+------------+-------+
Where Initial is the lowest "initial" km in that day by that id
and Final is the higher "Final" km in that day by that id
What do you suggest?
thanks
should work out like this:
SELECT street.Id
,street.Date
,Min(street.Initial) AS Iniziali
,Max(street.Final) AS Finali
,SUM(IIF(street.Kind = 'Red',street.Distance,0)) AS TotalRed
,SUM(IIF(street.Kind = 'Green',street.Distance,0)) AS TotalGreen
,Sum(street.Distance) AS Total
FROM street
GROUP BY street.Id
,street.Date
ORDER BY street.Date;

Summarize tables with percent of sum in single query

I have an ACTIVE_TRANSPORTATION table:
+--------+----------+--------+
| ATN_ID | TYPE | LENGTH |
+--------+----------+--------+
| 1 | SIDEWALK | 20.6 |
| 2 | SIDEWALK | 30.1 |
| 3 | TRAIL | 15.9 |
| 4 | TRAIL | 40.4 |
| 5 | SIDEWALK | 35.2 |
| 6 | TRAIL | 50.5 |
+--------+----------+--------+
It is related to an INSPECTION table via the ATN_ID:
+---------+--------+------------------+
| INSP_ID | ATN_ID | LENGTH_INSPECTED |
+---------+--------+------------------+
| 101 | 2 | 15.2 |
| 102 | 3 | 5.4 |
| 103 | 5 | 15.9 |
| 104 | 6 | 20.1 |
+---------+--------+------------------+
I want to summarize the information like this:
+----------+--------+-------------------+
| TYPE | LENGTH | PERCENT_INSPECTED |
+----------+--------+-------------------+
| SIDEWALK | 85.9 | 36% |
| TRAIL | 106.8 | 23% |
+----------+--------+-------------------+
How can I do this within a single query?
Here is the updated answer using ACCESS 2010. Note that LENGTH is reserved in ACCESS, so it needs to be changed to LENGTH_
SELECT
TYPE,
SUM(LENGTH) as LENGTH_,
SUM(IIF(ISNULL(LENGTH_INSPECTED),0, LENGTH_INSPECTED))/SUM(LENGTH) as PERCENT_INSPECTED
FROM
ACTIVE_TRANSPORTATION A
LEFT JOIN INSPECTION B
ON A.ATN_ID = B.ATN_ID
GROUP BY TYPE
Here is the answer using T-SQL in SQL SERVER 2014 I had originally
SELECT SUM(LENGTH) as LENGTH,
SUM(ISNULL(LENGTH_INSPECTED,0))/SUM(LENGTH) as PERCENT_INSPECTED,
TYPE
FROM
ACTIVE_TRANSPORTATION A
LEFT JOIN INSPECTION B
ON A.ATN_ID = B.ATN_ID
GROUP BY TYPE
Let me know if you need it to be converted to percent, rounded, etc, but I'm guessing that part is easy for you.