How to select a field when it is not in GroupBy clause - sql-server

I do not want to group by "BimeName.IssueDate" field in this select and I do not know how to do it.
If I don't specify this field in GroupBy clause I will get an error.
Msg 8120, Level 16, State 1, Line 2 Column 'BimeName.IssueDate' is
invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
Please help me!
SELECT
BimeName.IssueDate,
sum(BimeName.Premium) as Permium,
TypeOfInsurances.TypeOfInsurance + ' ' +
InsuranceKinds.KindOfInsurance as KindOfInsurance,
InsuranceAgents.NameOfInsurance,
InsuranceAgents.Representation + ' ' +
InsuranceAgents.AgentCode as Agent
from
BimeName
Inner Join InsuranceKinds ON InsuranceKinds.Id = BimeName.KindOfInsuranceId
Inner Join TypeOfInsurances ON TypeOfInsurances.Id = InsuranceKinds.TypeOfInsuranceId
Inner Join InsuranceAgents ON InsuranceAgents.Id = TypeOfInsurances.InsuranceAgentId
where
BimeName.IssueDate BETWEEN '2010-01-01' AND '2017-01-30'
group by InsuranceAgents.Representation, InsuranceAgents.NameOfInsurance, InsuranceAgents.AgentCode , BimeName.IssueDate , TypeOfInsurances.TypeOfInsurance , InsuranceKinds.KindOfInsurance

Just leave out the date field from select, if you, like you said, don't need it.
SELECT
sum(BimeName.Premium) as Permium,
TypeOfInsurances.TypeOfInsurance + ' ' +
InsuranceKinds.KindOfInsurance as KindOfInsurance,
InsuranceAgents.NameOfInsurance,
InsuranceAgents.Representation + ' ' +
InsuranceAgents.AgentCode as Agent
from
BimeName
Inner Join InsuranceKinds ON InsuranceKinds.Id = BimeName.KindOfInsuranceId
Inner Join TypeOfInsurances ON TypeOfInsurances.Id = InsuranceKinds.TypeOfInsuranceId
Inner Join InsuranceAgents ON InsuranceAgents.Id = TypeOfInsurances.InsuranceAgentId
where
BimeName.IssueDate BETWEEN '2010-01-01' AND '2017-01-30'
group by
InsuranceAgents.Representation,
InsuranceAgents.NameOfInsurance,
InsuranceAgents.AgentCode,
TypeOfInsurances.TypeOfInsurance,
InsuranceKinds.KindOfInsurance
You can have fields in where clause that are not in group by.

It doesn't make any sense. Imagine it has different values for field BimeName.IssueDate in a same group, so which value must be selected for that category? should think about it again.

Related

Select where in subquery from one row with CSV values

I'm trying to do a subquery where the value returned is a CSV list of values I want to use for the SELECT WHERE IN clause
SELECT *
FROM Facility.FacilityIO f
where f.FacilityID in (
select Facilities
from FacilityListView
where FacilityID = 'PSY35'
)
FacilityListView looks like this:
FacilityID Facilities
SOL1 SOL1,
PSY35 PSY3,PSY5
SOL1W SOL1,WSR1,
I get 0 results since SQL server is looking for a dataset and not an individual value but I don't know how to tell SQL server to select where f.FacilityID in ('PSY3','PSY5')
Join the tables and use the LIKE operator:
SELECT f.*
FROM Facility.FacilityIO f INNER JOIN FacilityListView v
ON ',' + v.Facilities + ',' LIKE '%,' + f.FacilityID + ',%'
WHERE v.FacilityID = 'PSY35'

How to SUM() appropriate rows in MSSQL query for one column with INNER JOIN?

I have a MSSQL query:
SELECT Artikel.ArtikelID, Artikel.K_HerstellerName AS ManufacturerName, Artikel.K_HerstellerPN AS ManufacturerPN, Artikel.ArtikelNummer AS SupplierPN, Artikel.Bezeichnung + ' - ' + Artikel.LangText AS Description,
Artikel.LetzterEK AS Price, Artikel.IstGesperrt AS Gesperrt, Lager.Verfuegbar AS Quantity, Lager.LagerPlatz AS LP
FROM Artikel INNER JOIN
Lager ON Artikel.ArtikelID = Lager.ArtikelID
WHERE (Artikel.K_HerstellerPN <> '') AND (Artikel.IstGesperrt = 'False') AND (Artikel.ArtikelNummer LIKE '%[0-9]-[0-9]%')
Here you can see how it looks like: https://ibb.co/fyOHv9
How to SUM() appropriate rows in MSSQL query for column "Quantity"?
In result all rows must be unique.
you need to group by all the columns that make each row unique, then use aggregate functions in your select, for example:
SELECT
MIN(Artikel.ArtikelID ) ArtikelID,
MIN(Artikel.K_HerstellerName) ManufacturerName,
SUM(Lager.Verfuegbar) Quantity
FROM Artikel
INNER JOIN Lager ON Artikel.ArtikelID = Lager.ArtikelID
WHERE (Artikel.K_HerstellerPN <> '') ...
GROUP BY
Artikel.ArtikelID,
Artikel.K_HerstellerName,
...

How to GROUP BY an alias

I trying to find the amount of classes each of our staff is scheduled to teach, I've counted the amount of times their staffID occurs in the schedule table, and it runs perfect if I only use a staff's first Name but for whatever reason it doesn't work when I try to concatenate their first and last name, and group by the assigned alias. What am I doing wrong?
SELECT DISTINCT sf.StfFirstName + ' ' + sf.StfLastname As StaffName, COUNT(fc.StaffID)
FROM Staff sf
JOIN Faculty_Classes fc
ON sf.StaffID = fc.StaffID
join Classes cl
ON fc.ClassID = cl.ClassID
GROUP BY Sf.StaffName
Just repeat the logic used in the select clause. It may look inefficient but it isn't. Note: Omit the alias given to that logic if pasting into the group by clause.
SELECT sf.StfFirstName + ' ' + sf.StfLastname As StaffName,
COUNT(fc.StaffID)
FROM Staff sf
JOIN Faculty_Classes fc
ON sf.StaffID = fc.StaffID
join Classes cl
ON fc.ClassID = cl.ClassID
GROUP BY sf.StfFirstName + ' ' + sf.StfLastname
;
You can also try without the concatenation, it should also work.
GROUP BY sf.StfFirstName, sf.StfLastname
Aliases created in the select clause are not reusable by the group by clause because the select clause actually gets performed after the group by, in other words the sequence of writing a sql query is not the sequence of operation.
You may repeat the logic as user Used_By_Already suggested or alternatively you can use a common table expression or derived table if you please:
common table expression:
with cte_example -- with name_of_cte as (your query)
as
(
SELECT sf.StfFirstName + ' ' + sf.StfLastname As StaffName, COUNT(fc.StaffID)
FROM Staff sf
JOIN Faculty_Classes fc
ON sf.StaffID = fc.StaffID
join Classes cl
ON fc.ClassID = cl.ClassID
)
select *
from cte_example
group by StaffName
derived table:
select *
from
(
SELECT sf.StfFirstName + ' ' + sf.StfLastname As StaffName, COUNT(fc.StaffID)
FROM Staff sf
JOIN Faculty_Classes fc
ON sf.StaffID = fc.StaffID
join Classes cl
ON fc.ClassID = cl.ClassID
) t1 --note the table alias
group by StaffName

SQL Stuff from Subquery

I have a query that returns a list of services and ContractorIDs. I need to stuff these services into a field to join them with another select statement by ContractorID, but I can't figure out how to do it.
The Select that lists the services is "
SELECT DISTINCT SM.ContractorID,
CASE WHEN S.bitRestrictedSelection = 1
THEN S.vchDescription + '*'
ELSE S.vchDescription
END AS vchDescription
FROM tblAscServiceRegionToOperator SRTO
INNER JOIN tblServiceMatrix SM
ON SRTO.OperatorID = 12624
AND SM.ServiceRegionID = SRTO.ServiceRegionID
AND SM.bitPrimaryService = 1
INNER JOIN tblServices S
ON S.ServiceID = SM.ServiceID
This produces the following:
In the example, for Contractor #16 He has 4 services I need to put them in one field called services by joining with another Select statement
I tried the following, but I get errors:
Select DISTINCT CompanyID, vchCompanyName as CompanyName,vchFIDNumber,vchPrimContactName, vchPrimContactEmail
,stuff((','
SELECT DISTINCT
SM.ContractorID,
CASE WHEN S.bitRestrictedSelection = 1
THEN S.vchDescription + '*'
ELSE S.vchDescription
END AS vchDescription
FROM tblAscServiceRegionToOperator SRTO
INNER JOIN tblServiceMatrix SM
ON SRTO.OperatorID = 12624
AND SM.ServiceRegionID = SRTO.ServiceRegionID
AND SM.bitPrimaryService = 1
INNER JOIN tblServices S
ON S.ServiceID = SM.ServiceID
FOR XML PATH('')
), 1, 1, '') as Services from tblCompany
Any assistance is greatly appreciated!!!
The following query would work:
SELECT SS.contractor Contractor,
STUFF((SELECT '; ' + US.vchdescription
FROM ServicesList US
WHERE US.contractor = SS.contractor
FOR XML PATH('')), 1, 1, '') [Services]
FROM ServicesList SS
GROUP BY SS.contractor
ORDER BY 1
I have created a table and inserted there two rows for contractor = 16, for you to get the idea.
You can use the suggestion given to you in the comments, to wrap the first select into a CTE and then perform the STUFF function on that CTE.
You can check a demo of this query here.

Intersect query with no duplicates

I have not used sql server in a large complex scale in years, and Looking for help on how to proper sintax intersect type query to joing these two data sets, and not create duplicate names. Some patients will have both an order and a clinical event entry and some will only have a clinical event.
Data Set 1
SELECT
distinct
ea.alias as FIN,
per.NAME_Last + ', ' + per.NAME_FIRST + ' ' + Isnull(per.NAME_MIDDLE, '') as PatientName,
oa.action_dt_tm as CirOrder,
od.ORIG_ORDER_DT_TM as DischOrder,
e.disch_dt_tm as ActualDisch,
prs.NAME_FULL_FORMATTED as OrderedBy,
from pathway py
join encounter e on e.CERNER_ENCOUNTER_ID = py.encntr_id
join encntr_alias ea on ea.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID and ea.ENCNTR_ALIAS_TYPE_WCD = 1049
join person per on per.CERNER_PERSON_ID = e.cerner_PERSON_ID
join orders o on o.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and o.CATALOG_wCD = '82111' -- communication order
and o.pathway_catalog_id = '43809296' ---Circumcision Order
join order_action oa on oa.[CERNER_ORDER_ID] = o.CERNER_ORDER_ID and oa.ACTION_TYPE_WCD = '2494'--ordered
join orders od on od.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and od.CATALOG_WCD = '203520' --- Discharge Patient
join prsnl prs on prs.CERNER_PERSON_ID = oa.order_provider_id
where py.pathway_catalog_id = '43809296' and ---Circumcision Order
oa.action_dt_tm > '2016-01-01 00:00:00'
and oa.ACTION_DT_TM < '2016-01-19 23:59:59'
--use the report prompts as parameters for the action_dt_tm
Data Set 2
SELECT
distinct e.[CERNER_ENCOUNTER_ID],
ea.alias as FIN,
per.NAME_Last + ', ' + per.NAME_FIRST + ' ' + Isnull(per.NAME_MIDDLE, '') as PatientName,
ce.EVENT_END_DT_TM as CircTime,
od.ORIG_ORDER_DT_TM as DischOrder,
e.disch_dt_tm as ActualDisch,
'' OrderedBy, -- should be blank for this set
cv.DISPLAY
from encounter e
join clinical_event ce on e.CERNER_ENCOUNTER_ID = ce.CERNER_ENCNTR_ID
join encntr_alias ea on ea.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID and ea.ENCNTR_ALIAS_TYPE_WCD = 1049
join person per on per.CERNER_PERSON_ID = e.cerner_PERSON_ID
join orders od on od.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and od.CATALOG_WCD = '203520' --- Discharge Patient
left outer join ENCNTR_LOC_HIST elh on elh.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID
left outer join CODE_VALUE cv on cv.CODE_VALUE_WK = elh.LOC_NURSE_UNIT_WCD
where ce.event_wcd = '201148' ---Newborn Circumcision
and ce.[RESULT_VAL] = 'Newborn Circumcision'
and ce.EVENT_END_DT_TM > '2016-01-01 00:00:00'
and ce.event_end_dt_tm < '2016-01-19 23:59:59’
and ce.RESULT_STATUS_WCD = '25'
and elh.ACTIVE_STATUS_DT_TM < ce.event_end_dt_tm -- Circ time between the location's active time and end time.
and elh.END_EFFECTIVE_DT_TM > ce.[EVENT_END_DT_TM]
--use the report prompts as parameters for the ce.[EVENT_END_DT_TM]
The structure of an intersect query is as simple as:
select statement 1
intersect
select statement 2
intersect
select statement 3
...
This will return all columns that are in both select statements. The columns returned in the select statements must be of the same quantity and type (or at least be convertible to common type).
You can also do an intersect type of query just using inner joins to filter out records in the one query that are not in the other. So for a simple example let's say you have two tables of colors.
Select distinct ColorTable1.Color
from ColorTable1
join ColorTable2
on ColorTable1.Color = ColorTable2.Color
This will return all the distinct colors in ColorTable1 that are also in ColorTable2. Using joins to filter could help your query perform better, but it does take more thought.
Also see: Set Operators (Transact-SQL)

Resources