Group rows when using case expresion - sql-server

I have the folloring query, that give me the next result:
select OBJ_POSITION,
CASE
WHEN (EVT_JOBTYPE = 'PM' and EVT_DESC like '%TMPL%') THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as HORAS_TMPL,
CASE
WHEN (EVT_JOBTYPE = 'CMS') THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as HORAS_SUST,
CASE
WHEN ((EVT_JOBTYPE = 'PM' and EVT_DESC like '%TMPL%') or (EVT_JOBTYPE = 'CMS')) THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as TOTAL_HORAS
from R5ACTIVITIES inner join R5EVENTS on ACT_EVENT = EVT_CODE inner join R5OBJECTS on EVT_OBJECT = OBJ_CODE
where OBJ_ORG = '156' and OBJ_POSITION like '156-EBM%' and EVT_STATUS = 'R' and EVT_TYPE in ('JOB', 'PPM')
group by OBJ_POSITION, EVT_JOBTYPE, EVT_DESC
OBJ_POSITION / HORAS_TMPL / HORAS_SUST / TOTAL_HORAS
156-EBM01 0 0 0
156-EBM01 0 0 0
156-EBM01 0 0 0
156-EBM02 0 0 0
156-EBM02 0 0 0
156-EBM03 0 0 0
156-EBM04 0 0 0
156-EBM04 8 0 8
156-EBM04 0.5 0 0.5
156-EBM04 0.75 0 0.75
156-EBM04 0 1.5 1.5
156-EBM05 0 0 0
156-EBM05 0 0 0
156-EBM05 0 0 0
The information is correct, but I only want one row per OBJ_Position, doing the sum of it's numbers (ACT_EST), like this:
OBJ_POSITION / HORAS_TMPL / HORAS_SUST / TOTAL_HORAS
156-EBM01 0 0 0
156-EBM02 0 0 0
156-EBM03 0 0 0
156-EBM04 9.25 1.5 10.75
156-EBM05 0 0 0
I've tried a lots of group by but none seems to work.
I think removing EVT_JOBTYPE from group by may work, but then it throws an error because its not an aggregate funcion. Same with EVT_DESC...

is this helpful.?
;with cte
As
(
select OBJ_POSITION,
CASE
WHEN (EVT_JOBTYPE = 'PM' and EVT_DESC like '%TMPL%') THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as HORAS_TMPL,
CASE
WHEN (EVT_JOBTYPE = 'CMS') THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as HORAS_SUST,
CASE
WHEN ((EVT_JOBTYPE = 'PM' and EVT_DESC like '%TMPL%') or (EVT_JOBTYPE = 'CMS')) THEN (SUM(CONVERT(float, ACT_EST)))
ELSE '0'
END as TOTAL_HORAS
from R5ACTIVITIES inner join R5EVENTS on ACT_EVENT = EVT_CODE inner join R5OBJECTS on EVT_OBJECT = OBJ_CODE
where OBJ_ORG = '156' and OBJ_POSITION like '156-EBM%' and EVT_STATUS = 'R' and EVT_TYPE in ('JOB', 'PPM')
group by OBJ_POSITION, EVT_JOBTYPE, EVT_DESC
)
Select OBJ_POSITION, SUM(HORAS_TMPL) as HORAS_TMPL,SUM(HORAS_SUST) as HORAS_SUST,SUM(TOTAL_HORAS) as TOTAL_HORAS
Group by OBJ_POSITION

Related

Combine like rows in table that used count function in the select

I am writing a query to access health information from my student information system for state and county record compliance. We are using SQL Server 2000 (legacy system) as the backend. The query is this:
select
i.Description Immunization,
Case
When si.Exempt = 'P' Then Count (LName)
Else 0
END AS 'Personal Exempt',
Case
When si.Exempt = 'M' Then Count (LName)
Else '0'
END AS 'Medical Exempt',
Case
When si.Exempt = 'R' Then Count (LName)
Else 0
END AS 'Religious Exempt',
Case
When si.Exempt = 'I' Then Count (LName)--AS 'Personal Exemption'
Else '0'
END AS 'Had Illness'
from student cross join immunization i left join StImmunization si on si.sno = Student.sno and si.immcode = i.code
where Student.Status = 'A' and i.TotalReq > 0
Group BY i.Description, si.exempt
The output is this:
Immunization PersonalExempt MedicalExempt RelgiousExempt HadIllness
Chicken pox (Varicella) 0 0 0 6
Chicken pox (Varicella) 1 0 0 0
Hepatitis B 1 0 0 0
T_DAP 0 0 0 0
Polio 0 0 0 0
Diptheria, Tetanus,
Pertussis 0 0 0 0
Hepatitis B 0 0 0 0
Diptheria, Tetanus,
Pertussis 0 0 0 0
MMR 0 0 0 0
T_DAP 1 0 0 0
MMR 1 0 0 0
Polio 1 0 0 0
Chicken pox (Varicella) 1 0 0 0
I would like the output to combine the like rows of the columns so it looks like this and if necessary add like row and columns:
Imunization PersonalExempt Medical Exempt Religious Exempt Had Illness
Chicken pox (Varicella) 2 0 0 6
Hepatitis B 1 0 0 0
T_DAP 1 0 0 0
Polio 1 0 0 0
Diptheria, Tetanus,
Pertussis 1 0 0 0
Notice row one (below) is the sum of rows 2 and 13 (above). Any ideas on how to accomplish this?
Better to use SUM here -- then you can select a 1 or 0 to make the sum give the count.
Old SQL GROUP BY trick.
select
i.Description AS Immunization,
SUM(Case When si.Exempt = 'P' Then 1 Else 0 END) AS 'Personal Exempt',
SUM(Case When si.Exempt = 'M' Then 1 Else 0 END) AS 'Medical Exempt',
SUM(Case When si.Exempt = 'R' Then 1 Else 0 END) AS 'Religious Exempt',
SUM(Case When si.Exempt = 'I' Then 1 Else 0 END) AS 'Had Illness'
from student cross join immunization i left join StImmunization si on si.sno = Student.sno and si.immcode = i.code
where Student.Status = 'A' and i.TotalReq > 0
Group BY i.Description

pivot day of the month from row to column with sum value

I have a data with sum value and mapping to the day that matched with this SQL
sample data and code
http://sqlfiddle.com/#!3/ca364/6
but my problem is I can't pivot a date row to column
i need to pivot (query from sqlfiddle above) to shown as this example
Date 1 2 3 4 5 6 7 8 9 to end of the month
TAS0B065B999P999 0 0 0 0 0 4900 9900 0 -96600
TAS1B065B999P999 0 0 0 0 0 0 0 0 0
TAS2B065B999P999 0 0 0 0 0 0 0 0 0
TAS3B065B999P999 0 0 0 0 0 0 0 0 0
TAS4B065B999P999 0 0 0 0 0 0 0 0 0
TAS5B065B999P999 0 0 0 0 0 0 0 0 0
TAS6B065B999P999 0 0 0 0 0 0 0 0 0
TAS7B065B999P999 0 0 0 0 0 0 0 0 0
TAS8B065B999P999 0 0 0 0 0 0 0 0 0
TAS9B065B999P999 0 0 0 0 0 0 0 0 0
TASAB065B999P999 0 0 0 0 0 0 0 0 0
TDS1B065B999P999 0 0 0 0 0 0 0 0 0
TDS2B065B999P999 0 0 0 0 0 0 0 0 0
TDS3B065B999P999 0 0 0 0 0 0 0 0 0
TRS1B065B999P999 0 0 0 0 0 0 0 0 0
TRS2B065B999P999 0 0 0 -72900 0 74900 -74900 90900 0
TRS3B065B999P999 0 0 0 21100 0 0 0 0 0
Sample code
WITH t1
AS (SELECT dt,TERM,
SumCashOUT,
DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', dt), '1900-01-01') AS firstInMonth,
DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', dt)+1, '1900-01-01')) AS lastInMonth
FROM
(
SELECT CONVERT( DATE, TA_DATE) AS dt,TERM,
DATENAME(dw, CONVERT( DATE, TA_DATE)) AS dn,
DATEPART(DW, CONVERT( DATE, TA_DATE)) AS dtdw,
OUT1 + OUT2 + OUT3 + OUT4 AS SumCashOUT
FROM CASH1609
GROUP BY TA_DATE,
TERM,
OUT1,
OUT2,
OUT3,
OUT4
) AS st
GROUP BY dt,TERM,
dn,
dtdw,
SumCashOUT),
Calendar
AS (SELECT DISTINCT
DATEADD(Day, c.number, t1.firstInMonth) AS d
FROM t1
JOIN master..spt_values AS c ON type = 'P'
AND DATEADD(DAY, c.number, t1.firstInMonth) BETWEEN t1.firstInMonth AND t1.lastInMonth)
SELECT DATEPART(dd, d) AS Date,TERM,
CASE
WHEN CONVERT( NUMERIC(16, 0), SumCashOUT) IS NULL
THEN 0
ELSE CONVERT(NUMERIC(16, 0), SumCashOUT)
END AS SumCashOUT
FROM calendar AS c
LEFT JOIN t1 ON t1.dt = c.d
LEFT JOIN holiday ON c.d = holiday.HDATE
ORDER BY DAte ASC;
You will have to use PIVOT Command in SQL Server.
This will deliver the desired output:
;WITH tab (TERM, DOM, CASH) AS
(
SELECT TERM,
DAY(CAST(TA_DATE AS DATE)) AS DOM,
OUT1 + OUT2 + OUT3 + OUT4 AS CASH
FROM CASH1609
)
SELECT *
FROM tab
PIVOT
(
SUM (CASH)
FOR DOM IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],
[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],
[22],[23],[24],[25],[26],[27],[28],[29],[30],[31])
) AS pvt
The "tab" CTE prepares the Columns DOM(Day-Of-Month) and CASH.
PIVOT needs an aggregate function (SUM in your case) AND the possible values for the pivot-column.
Note: This will deliver NULL for each non-existing DOM, just replace
SELECT * FROM tab
with
SELECT TERM, COALESCE([1],0), COALESCE([2],0), etc... FROM tab...

Count data using SQL Server 2008

I'm using SQL Server 2008 and I have a big database, I need to count the data for every manzana but every rows is 0 so I don't know how to do that
SELECT
Manzana,
SUM(CASE WHEN Manzana IN( 'CBrc','CBrc1', 'CBrc2') THEN 1 ELSE 0 END )AS CBrc,
SUM(CASE WHEN Manzana IN ('W1','W11','W12','W13','W14','W15','W16') THEN 1 ELSE 0 END) AS W1,
SUM(CASE WHEN Manzana IN('PC1','PC11') THEN 1 ELSE 0 END) AS PC1,
SUM(CASE WHEN Manzana IN ('CLu','CLU1') THEN 1 ELSE 0 END) AS CLu,
SUM(CASE WHEN Manzana IN('S3','S31') THEN 1 ELSE 0 END) AS S3,
SUM(CASE WHEN Manzana IN ('C2L') THEN 1 ELSE 0 END) AS C2L,
SUM(CASE WHEN Manzana IN ('PCA') THEN 1 ELSE 0 END) AS PCA,
SUM(CASE WHEN Manzana IN ('ADO') THEN 1 ELSE 0 END) AS AD,
SUM(CASE WHEN Manzana IN ('PRC') THEN 1 ELSE 0 END) AS CBu,
SUM(CASE WHEN Manzana IN('SIN') THEN 1 ELSE 0 END) AS SIN_ACCESO_A_INFORMACION
FROM
dbo.Hoja3$
GROUP BY
Manzana
I need to obtain something like this
Manzana CBrc W1 PC1 CLU S3 C2L
5445 8 11 0 0 0 0
4545 15 0 30 0 0 0
5455 21 0 5 3 2 0
7893 0 0 3 1 0 0
1566 100 4 1 0 0 80
You can't group by Manzana and not group by Manzana. Also, from the sample data, I can tell that you haven't provided enough information. Just from the first row:
Manzana CBrc W1 PC1 CLU S3 C2L
5445 8 11 0 0 0 0
If Manzana is 5445, then what column has the value CBrc? It can't be the Manzana column, but has to be some other column. In this vacuum of information, I'm going to call the mystery column Code.
Then try this (of course, you'll need to put all your code groups in):
WITH CodeGroupings AS (
SELECT * FROM (VALUES -- Do this in a permanent table instead!
('CBrc%', 'CBrc'), -- can use wildcards
('W1_', 'W1'), -- or single letter wildcards
('PC1', 'PC1'), -- or just put individual values
('PC11', 'PC1'), -- mapping to the same group as the previous line
('SIN', 'SIN_ACCESO_A_INFORMACION')
) M (CodePattern, CodeGroup)
), ManzanaCodeGroups AS (
SELECT
H.Manzana,
CG.CodeGroup
FROM
dbo.Hoja3$ H
CROSS APPLY (
SELECT TOP 1 *
FROM CodeGroupings CG
WHERE H.Code LIKE CG.CodePattern
) CG
)
SELECT
*
FROM
ManzanaCodeGroups
PIVOT (Count(*) FOR (CodeGroup IN CBrc, W1, PC1, SIN_ACCESO_A_INFORMACION)) P
;
After reading your comment "I try to count how many Cbrc,Pc1, Clu etc I have in every Manzana" I see the problem.
You're using the IN operator incorrectly.
To test fo the occurrence of a substring use the CHARINDEX function:
SELECT
Manzana,
SUM( CASE WHEN CHARINDEX( 'SIN', Manzana ) > 0 THEN 1 ELSE 0 END ) AS SIN,
SUM( CASE WHEN CHARINDEX( 'PCA', Manzana ) > 0 THEN 1 ELSE 0 END ) AS PCA,
...
FROM
Hoja3$
GROUP BY
Manzana

How to calculate the Average of fields that are not zero in SQL Server?

I have a few columns: Week1, Week2, Week3, Week4, Week5
i.e.
Week1 = 5
Week2 = 0
Week3 = 10
Week4 = 7
Week5 = 0
How do I calculate the average based on the fields that are not zero?
Incorrect:
(5+0+10+7+0)/5 = 4.4
Correct:
(5+0+10+7+0)/3 = 7.3
How to let create a custom column to let the SQL know that I only want to divide by 3 instead of 5?
If one or more columns are not zero, then they are averaged as you expected.
To obtain a null when all are zero:
select (week1+week2+week3+week4+week5)/
nullif(
case when week1=0 then 0 else 1 end +
case when week2=0 then 0 else 1 end +
case when week3=0 then 0 else 1 end +
case when week4=0 then 0 else 1 end +
case when week5=0 then 0 else 1 end,
0)
from ....
To obtain a zero when all are zero:
select
coalesce((week1+week2+week3+week4+week5)/
nullif(
case when week1=0 then 0 else 1 end +
case when week2=0 then 0 else 1 end +
case when week3=0 then 0 else 1 end +
case when week4=0 then 0 else 1 end +
case when week5=0 then 0 else 1 end,
0),0)
from ....
And if you want to be safe with null on columns:
select
coalesce((
coalesce(week1,0) +
coalesce(week2,0) +
coalesce(week3,0) +
coalesce(week4,0) +
coalesce(week5,0)
)/
nullif(
case when coalesce(week1,0)=0 then 0 else 1 end +
case when coalesce(week2,0)=0 then 0 else 1 end +
case when coalesce(week3,0)=0 then 0 else 1 end +
case when coalesce(week4,0)=0 then 0 else 1 end +
case when coalesce(week5,0)=0 then 0 else 1 end,
0),0)
from ....
As a note, these types of problems (aggregation within a row) are often more easily expressed using apply:
select a.average
from table t cross apply
(select avg(nullif(val, 0)) as average
from (values (t.week1),
(t.week2),
(t.week3),
(t.week4),
(t.week5)
) v(val)
) a;

Stored procedure: "A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations"

I can't find what's wrong with the SELECT statement I'm trying to use on a stored procedure:
SELECT TOP 1 #TARIF = t.rea_est_tax_cla_ali_area,
#CHARACTERISTIC = t.rea_est_cha_id,
#USE = t.rea_est_use_id,
#TYPE = t.typ_rea_est_id,
( ( CASE
WHEN t.rea_est_tax_cla_ali_area IS NULL THEN 1
ELSE 0
END ) + ( CASE
WHEN t.rea_est_cha_id IS NULL THEN 1
ELSE 0
END ) + ( CASE
WHEN t.rea_est_use_id IS NULL THEN 1
ELSE 0
END ) + ( CASE
WHEN t.typ_rea_est_id IS NULL
THEN 1
ELSE 0
END ) ) AS NULLCOLUMNCOUNT
FROM dbo.tbl_real_estate_tax_classifier
Any help appreciated, I can't submit the entire procedure because of work regulations but the problem appears to be there.
I reformatted your code with line breaks for readability.
SELECT TOP 1
#TARIF = T.REA_EST_TAX_CLA_ALI_AREA,
#CHARACTERISTIC = T.REA_EST_CHA_ID,
#USE = T.REA_EST_USE_ID,
#TYPE = T.TYP_REA_EST_ID,
((CASE WHEN T.REA_EST_TAX_CLA_ALI_AREA IS NULL THEN 1 ELSE 0 END)+(CASE WHEN T.REA_EST_CHA_ID IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN T.REA_EST_USE_ID IS NULL THEN 1 ELSE 0 END)+(CASE WHEN T.TYP_REA_EST_ID IS NULL THEN 1 ELSE 0 END)) AS NULLCOLUMNCOUNT
FROM dbo.TBL_REAL_ESTATE_TAX_CLASSIFIER
Hopefully you see the problem now. NULLCOLUMNCOUNT is your culprit.
Did you mean to write this?
SELECT TOP 1
#TARIF = T.REA_EST_TAX_CLA_ALI_AREA,
#CHARACTERISTIC = T.REA_EST_CHA_ID,
#USE = T.REA_EST_USE_ID,
#TYPE = T.TYP_REA_EST_ID,
#NULLCOLUMNCOUNT = ((CASE WHEN T.REA_EST_TAX_CLA_ALI_AREA IS NULL THEN 1 ELSE 0 END)+(CASE WHEN T.REA_EST_CHA_ID IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN T.REA_EST_USE_ID IS NULL THEN 1 ELSE 0 END)+(CASE WHEN T.TYP_REA_EST_ID IS NULL THEN 1 ELSE 0 END))
FROM dbo.TBL_REAL_ESTATE_TAX_CLASSIFIER
The error seems pretty clear - you are using part of the select to assign values to variables and part to return as a column.
Maybe you want something like this?
SELECT TOP 1
#TARIF = T.REA_EST_TAX_CLA_ALI_AREA,
#CHARACTERISTIC = T.REA_EST_CHA_ID,
#USE = T.REA_EST_USE_ID,
#TYPE = T.TYP_REA_EST_ID,
#NULLCOLUMNCOUNT = ((CASE WHEN T.REA_EST_TAX_CLA_ALI_AREA IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN T.REA_EST_CHA_ID IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN T.REA_EST_USE_ID IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN T.TYP_REA_EST_ID IS NULL THEN 1 ELSE 0 END))
FROM dbo.TBL_REAL_ESTATE_TAX_CLASSIFIER

Resources