group By in sql not assigning the value - sql-server

i am having the value in column Description , 'TRANSPORT' , in that particular table the same value has two times, i need to make it as a single value , in that i am using group by . but its not assigning.
my query
SELECT CONVERT(date, UC.USGDATE) as USGDATE, SG.DESCRIPTION, SG.SERVICEGRP
FROM APP_SYUTILITYCHARGES UC LEFT OUTER JOIN
TX_MYSERVICEITEM SI
ON SI.SERVICEITEMID = UC.SERVICEITEMID LEFT OUTER JOIN
TX_MYSERVICE MS
ON MS.SERVICEID = SI.SERVICEID LEFT OUTER JOIN
TX_SERVICEGROUP SG
ON SG.SERVICEGRP = MS.SERVICEGRP
WHERE UC.STAYID = #STAYID
GROUP BY SG.SERVICEGRP, UC.USGDATE, SG.DESCRIPTION

I suspect the problem is the group by clause. If you want to get one value per date, then you need the CONVERT() in the GROUP BY as well as the SELECT:
SELECT CONVERT(date, UC.USGDATE) as USGDATE, SG.DESCRIPTION, SG.SERVICEGRP
FROM APP_SYUTILITYCHARGES UC LEFT OUTER JOIN
TX_MYSERVICEITEM SI
ON SI.SERVICEITEMID = UC.SERVICEITEMID LEFT OUTER JOIN
TX_MYSERVICE MS
ON MS.SERVICEID = SI.SERVICEID LEFT OUTER JOIN
TX_SERVICEGROUP SG
ON SG.SERVICEGRP = MS.SERVICEGRP
WHERE UC.STAYID = #STAYID
GROUP BY SG.SERVICEGRP, CONVERT(date, UC.USGDATE), SG.DESCRIPTION

Because of this type of grouping GROUP BY SG.SERVICEGRP,UC.USGDATE,SG.DESCRIPTION , the combination may be unique so you will be get description two times.

Related

Group the count values

I want to get the count of property and building and building is linked with property. Below is the query I tried:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName,P.PropertyID
I expect values group of type
and I want to group the count with out duplicate of property-type name
sry for bad English.
Try to use the SUM() function on this subquery
Returns the sum of all the values, or only the DISTINCT values, in the expression. SUM can be used with numeric columns only. Null values are ignored.
MSDN
SUM(Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID = P.PropertyID)
When you use GROUP BY then it groups data by columns which you've written in GROUP BY statement. You've written :
GROUP BY PT.PropertyTypeName,P.PropertyID`
it means that SQL Engine will get all unique combinations of PropertyTypeName, PropertyID. However, you want just unique PropertyTypeName. So write just this field into GROUP BY statement:
GROUP BY PT.PropertyTypeName
So complete query will look like this:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName

IN clause not working within subquery inner join

I am trying to pull a list of most recent lab values in 2015. All lab value are stored in one table and I need to both limit the data to be within 2015 and limit it to certain types of labs so the max date doesn't give me the most recent lab regardless of type. Although I use the IN clause, labs of other types are included. I need the last value regardless of what type of lab they have as long as it's within the types identified in the IN clause (i.e. I don't need the last value of each type)
select distinct
t2.pat_id
,t2.pat_last_name "PatientLast"
,t2.pat_first_name "PatFirst"
,t2.birth_date
,t1.contact_date "ContactDate"
,t3.name "EncounterType"
,t4.ord_num_value "Numeric Value"
,t4.result_date
from table1 t1
inner join table2 t2 on t1.pat_id = t2.pat_id
inner join table3 t3 on t1.enc_type_c = t3.disp_enc_type_c
inner join table4 t4 on t1.pat_enc_csn_id = t4.pat_enc_csn_id
inner join
(
select
table1.pat_id
,max(table1.contact_date) as LastResult
,table4.component_id
from table1
**inner join order_results on table1.pat_enc_csn_id = table4.pat_enc_csn_id
where table4.component_id in ('1526664','1558024','1004','2667', '1230000002','1564041')
and table1.contact_date between '2015-01-01' and '2015-12-31'
group by table1.pat_id, table4.component_id
) enc2** on table1.pat_id = enc2.pat_id
and table1.contact_date = enc2.LastResult
order by table2.pat_last_name, table2.pat_first_name
Your query is a bit hard to follow. But one method is to use row_number(). Something like this:
select t.*
from (select . . .,
row_number() over (partition by pat_id order by contact_date desc) as seqnum
from . . .
where . . .
) t
where seqnum = 1;
You have where conditions in the subquery that are not in the outer query, so it is hard to follow the intended logic. The use of row_number() is much simpler than a subquery, because you don't have to repeat any logic.

How to join one select with another when the first one not always returns a value for specific row?

I have a complex query to retrieve some results:
EDITED QUERY (added the UNION ALL):
SELECT t.*
FROM (
SELECT
dbo.Intervencao.INT_Processo, analista,
ETS.ETS_Sigla, ATC.ATC_Sigla, PAT.PAT_Sigla, dbo.Assunto.SNT_Peso,
CASE
WHEN ETS.ETS_Sigla = 'PE' AND (PAT.PAT_Sigla = 'LIB' OR PAT.PAT_Sigla = 'LBR') THEN (0.3*SNT_Peso)
WHEN ETS.ETS_Sigla = 'CD' THEN (0.3*SNT_Peso)*0.3
ELSE SNT_Peso
END AS PESOAREA,
CASE
WHEN a.max_TEA_FimTarefa IS NULL THEN a.max_TEA_InicioTarefa
ELSE a.max_TEA_FimTarefa
END AS DATA_INICIO_TERMINO,
ROW_NUMBER() OVER (PARTITION BY ATC.ATC_Sigla, a.SRV_Id ORDER BY TEA_FimTarefa DESC) AS seqnum
FROM dbo.Tarefa AS t
INNER JOIN (
SELECT
MAX(dbo.TarefaEtapaAreaTecnica.TEA_InicioTarefa) AS max_TEA_InicioTarefa,
MAX (dbo.TarefaEtapaAreaTecnica.TEA_FimTarefa) AS max_TEA_FimTarefa,
dbo.Pessoa.PFJ_Descri AS analista, dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id
FROM dbo.TarefaEtapaAreaTecnica
LEFT JOIN dbo.Tarefa ON dbo.TarefaEtapaAreaTecnica.TRF_Id = dbo.Tarefa.TRF_Id
LEFT JOIN dbo.AreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.AreaTecnica.ATC_Id
LEFT JOIN dbo.ServicoAreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.ServicoAreaTecnica.ATC_Id
AND dbo.Tarefa.SRV_Id = dbo.ServicoAreaTecnica.SRV_Id
INNER JOIN dbo.Pessoa ON dbo.Pessoa.PFJ_Id = dbo.ServicoAreaTecnica.PFJ_Id_Analista
GROUP BY dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id, dbo.Pessoa.PFJ_Descri
) AS a ON t.SRV_Id = a.SRV_Id
INNER JOIN dbo.TarefaEtapaAreaTecnica AS TarefaEtapaAreaTecnica_1 ON
t.TRF_Id = TarefaEtapaAreaTecnica_1.TRF_Id
AND a.ATC_Id = TarefaEtapaAreaTecnica_1.ATC_Id
AND a.max_TEA_InicioTarefa = TarefaEtapaAreaTecnica_1.TEA_InicioTarefa
LEFT JOIN AreaTecnica ATC ON TarefaEtapaAreaTecnica_1.ATC_Id = ATC.ATC_Id
LEFT JOIN Etapa ETS ON TarefaEtapaAreaTecnica_1.ETS_Id = ETS.ETS_Id
LEFT JOIN ParecerTipo PAT ON TarefaEtapaAreaTecnica_1.PAT_Id = PAT.PAT_Id
LEFT OUTER JOIN dbo.Servico ON a.SRV_Id = dbo.Servico.SRV_Id
INNER JOIN dbo.Intervencao ON dbo.Servico.INT_Id = dbo.Intervencao.INT_Id
LEFT JOIN dbo.Assunto ON dbo.Servico.SNT_Id = dbo.Assunto.SNT_Id
) t
The result is following:
It works good, the problem is that I was asked that if when a row is not present on this query, it must contain values from another table (ServicoAreaTecnica), so I got this query for the other table based on crucial information of the first query. So if I UNION ALL I get this:
Query1 +
UNION ALL
SELECT INN.INT_Processo,
PES.PFJ_Descri,
NULL, --ETS.ETS_Sigla,
ART.ATC_Sigla,
NULL ,--PAT.PAT_Sigla,
ASS.SNT_Peso,
NULL, --PESOAREA
NULL, --DATA_INICIO_TERMINO
NULL --seqnum
FROM dbo.ServicoAreaTecnica AS SAT
INNER JOIN dbo.AreaTecnica AS ART ON ART.ATC_Id = SAT.ATC_Id
INNER JOIN dbo.Servico AS SER ON SER.SRV_Id = SAT.SRV_Id
INNER JOIN dbo.Assunto AS ASS ON ASS.SNT_Id = SER.SNT_Id
INNER JOIN dbo.Intervencao AS INN ON INN.INT_Id = SER.INT_Id
INNER JOIN dbo.Pessoa AS PES ON PES.PFJ_Id = SAT.PFJ_Id_Analista
The result is following:
So what I want to do is to remove row number 1 because row number 2 exists on the first query, I think I got it explained better this time. The result should be only row number 1, row number 2 would appear only if query 1 doesn't retrieve a row for that particular INN.INT_Processo.
Thanks!
Ok, there are two ways to reduce your record set. Given that you've already written the code to produce the table with the extra rows, it might be easiest to just add code to reduce that:
Select * from
(Select *
, Row_Number() over
(partition by IntProcesso, Analista order by ISNULL(seqnum, 0) desc) as RN
from MyResults) a
where RN = 1
This will assign row_number 1 to any rows that came from your first query, or to any rows from the second query that do not have matches in the first query, then filter out extra rows.
You could also use outer joins with isnull or coalesce, as others have suggested. Something like this:
Select ISNULL(a.IntProcesso, b.IntProcesso) as IntProcesso
, ISNULL(a.Analista, b.Analista) as Analista
, ISNULL(a.ETSsigla, b.ETSsigla) as ETSsigla
[repeat for the rest of your columns]
from Table1 a
full outer join Table2 b
on a.IntProcesso = b.IntProcesso and a.Analista = b.Analista
Your code is hard to read, because of the lengthy names of everything (and to be honest, the fact that they're in a language I don't speak also makes it a lot harder).
But how about: replacing your INNER JOINs with LEFT JOINs, adding more LEFT JOINs to draw in the alternative tables, and introducing ISNULL clauses for each variable you want in the results?
If you do something like ... Query1 Right Join Query2 On ... that should get only the rows in Query2 that don't appear in Query 1.

Count by group as part of a SQL Server query

I have the following SQL server query:
SELECT G.StyleID,
G.Size, Count(*) As 'Count',
G.PropertyID FROM TBL_Garment G
LEFT OUTER JOIN TBL_EmployeeJob ON TBL_EmployeeJob.ID = G.EmployeeJobID
LEFT OUTER JOIN TBL_DepartmentJob ON TBL_DepartmentJob.ID = TBL_EmployeeJob.DepartmentJobID
LEFT OUTER JOIN TBL_Department ON TBL_Department.ID = TBL_DepartmentJob.DepartmentID
LEFT OUTER JOIN TBL_Division ON TBL_Division.ID = TBL_Department.DivisionID
LEFT OUTER JOIN TBL_Job ON TBL_Job.ID = TBL_DepartmentJob.JobID
WHERE G.EmployeejobiD IS NOT NULL
AND TBL_Division.ID = N'1'
AND TBL_Department.ID = N'1'
AND TBL_Job.ID = N'1'
AND G.PropertyID = 1
GROUP BY G.StyleID, G.Size, G.PropertyID
ORDER BY G.StyleID
and here are the results returned by this query:
Now I need 2 extra columns in this table:
One is the sum of the count by StyleID (As Total), and the other is Count/Total.
I am sure I can get the count/Total on my own, but do not know how to get the Total column, or even if it is possible.
Below is a version of how I would like the table to be:
You can use a windowing function:
sum([Count]) over (partition by [StyleID])
Make sure it's good enough for you performance-wise, though.

Group by in SQL Server

I have a query in SQL Server
SELECT
k12_dms_contacts_master.prefix_id AS prefix,
k12_dms_contacts_master.first_name,
k12_dms_contacts_master.last_name,
k12_dms_contacts_master.email,
k12_dms_institution_master.inst_name,
k12_dms_institution_master.address,
k12_dms_cities.name AS city_name,
k12_dms_zip_codes.zip_code,
k12_dms_institution_master.type_id,
k12_dms_contacts_institution_jobtitles.glevel_id,
k12_dms_districts.name AS district_name,
k12_dms_counties.name AS county_name,
k12_dms_institution_master.state_id,
k12_dms_institution_master.phone,
k12_dms_contacts_institution_jobtitles.job_title_id
FROM
k12_dms_institution_master
INNER JOIN k12_dms_contacts_institution_jobtitles ON k12_dms_contacts_institution_jobtitles.inst_id = k12_dms_institution_master.id
INNER JOIN k12_dms_contacts_master ON k12_dms_contacts_institution_jobtitles.contact_id = k12_dms_contacts_master.id
INNER JOIN k12_dms_cities ON k12_dms_cities.id = k12_dms_institution_master.city_id
INNER JOIN k12_dms_districts ON k12_dms_districts.id = k12_dms_institution_master.district_id
INNER JOIN k12_dms_counties ON k12_dms_counties.id = k12_dms_institution_master.county_id
INNER JOIN k12_dms_zip_codes ON k12_dms_zip_codes.id = k12_dms_institution_master.zip_code_id
WHERE
k12_dms_zip_codes.zip_code IN ('92678', '92679', '92688', '92690', '92691', '92692', '92693', '92694', '92877',
'92879', '92881', '92883')
ORDER BY
k12_dms_institution_master.state_id,
k12_dms_institution_master.inst_name ASC
Now I want to perform GROUP BY on Email address and Institution name but I am getting this error :
Column 'k12_dms_contacts_master.prefix_id' is invalid in the select
list because it is not contained in either an aggregate function or
the GROUP BY clause.
Any help would be highly appreciable.
The error message says it all.
You have created a group and since this column is not part of the "group by" nor an aggregation of all the groups column (like sum or count) you can't use it in the select clause.
Please note that the return of a group by is one row per group. Logically, that column would be different for any group member so it can not fit one line!

Resources