sql group by with left join - sql

fail statement:Error: ORA-00979: not a GROUP BY expression
select org_division.name , org_department.name , org_surveylog.division_code as divisionCode,org_surveylog.department_code as departmentCode , max(org_surveylog.actiondate) from org_surveylog
left join org_division on (org_surveylog.division_code= org_division.division_code and org_surveylog.SURVEY_NUM= org_division.survey_num)
left join org_department on (org_surveylog.department_code = org_department.department_code and org_surveylog.SURVEY_NUM = org_department.survey_num)
group by org_surveylog.division_code,org_surveylog.department_code
but below is ok
select org_surveylog.division_code as divisionCode,org_surveylog.department_code as departmentCode , max(org_surveylog.actiondate) from org_surveylog
left join org_division on (org_surveylog.division_code= org_division.division_code and org_surveylog.SURVEY_NUM= org_division.survey_num)
left join org_department on (org_surveylog.department_code = org_department.department_code and org_surveylog.SURVEY_NUM = org_department.survey_num)
group by org_surveylog.division_code,org_surveylog.department_code
how to use group by with left join when i need to show value of org_division.name , org_department.name ?

You need to change your GROUP BY to
group by org_division.name ,
org_department.name
org_surveylog.division_code,
org_surveylog.department_code
From Oracle Select Statements : Select Statement With GROUP BY Clause
SELECT <column_name>, <aggregating_operation>
FROM <table_name>
GROUP BY <column_name>;
You will notice that you need to include the non aggregated columns in the GROUP BY statement.

Related

converting a sql query without sub query

Is there a way to convert this query into one without having the subquery in where clause?
select distinct
ie.install_id
, ie.sp_id
, ie.device_config_id
from d1_sp sp
inner join install_evt ie
on ie.sp_id = sp.sp_id
where ie.install_dttm = (select max(iemax.install_dttm)
from install_evt iemax
where iemax.sp_id = sp.sp_id)
select distinct
ie.install_id
, ie.sp_id
, ie.device_config_id
, max(ie.install_dttm)
from d1_sp sp
inner join install_evt ie
on ie.sp_id = sp.sp_id
group by ie.install_id, ie.sp_id, ie.device_config_id
if you need additional grouping you can use an order by

Not able to apply join in sql query

i want to add the join "JOIN {User}
ON {Deck}.[CreatedBy] = {User}.[Id]" in following query. I tried many combination but not succeeded. i want to fetch Name from User table
SELECT #CampaignQueryFilterString AS [Selected],
{Deck}.[Id], {Deck}.[Name],
{User}.[Name],
{Deck}.[TableOfContentId], {Deck}.[CreatedBy],
{Deck}.[LastModifiedOn], {Deck}.[ExpiryDate],s1.[Count]
FROM {Deck}
JOIN
(
SELECT {Deck}.[Id],
LISTAGG( {TagValue}.[Id], ',' ) WITHIN GROUP (ORDER BY {TagValue}.[TagCategoryId] ) AS Tags
FROM {Deck}
JOIN {AssociatedDeckTags}
ON {AssociatedDeckTags}.[DeckId] = {Deck}.[Id]
JOIN {TagValue}
ON {AssociatedDeckTags}.[TagValueId] = {TagValue}.[Id]
WHERE {Deck}.[IsPublished] = 1
AND {Deck}.[IsActive] = 1 AND {Deck}.[ReplacedByDeckId] IS NULL
AND {Deck}.[TableOfContentId] IN #TableOfContentIdFilterString
AND {Deck}.[ContentFileTypeId] IN #AllowedContentType
AND {Deck}.[ExpiryDate] > SYSDATE
GROUP BY {Deck}.[Id]
) DeckView
ON {Deck}.[Id] = DeckView.Id
JOIN(
SELECT COUNT(*) AS [Count], {DeckGroup}.[DeckId] AS [S1DeckId]
FROM {DeckGroup}
JOIN {Slide} ON {Slide}.[DeckGroupId] = {DeckGroup}.[Id]
GROUP BY {DeckGroup}.[DeckId]
) s1 ON s1.[S1DeckId] = {Deck}.[Id]
#RegexString
#SearchFilter
#CreatedBy
GROUP BY
{Deck}.[Id], {Deck}.[Name], {Deck}.[TableOfContentId],
{Deck}.[CreatedOn], {Deck}.[CreatedBy],
{Deck}.[LastModifiedOn], {Deck}.[ExpiryDate],
{Deck}.[NumOfPreviews], {Deck}.[NumOfDownloads],s1.[Count]
ORDER BY #Orderby
Looks like simply join, please try the below query (using your notation). I added left join and in group by clause - {User}.[Name]. Optionally you can use some aggregating function for {User}.[Name] - max(), listagg() and remove it from group by clause.
SELECT #CampaignQueryFilterString AS [Selected],
{Deck}.[Id], {Deck}.[Name], {User}.[Name], {Deck}.[TableOfContentId],
{Deck}.[CreatedBy], {Deck}.[LastModifiedOn], {Deck}.[ExpiryDate], s1.[Count]
FROM {Deck}
JOIN DeckView ON {Deck}.[Id] = DeckView.Id -- subquery1
JOIN s1 ON s1.[S1DeckId] = {Deck}.[Id] -- subquery2
LEFT JOIN {User} ON {Deck}.[CreatedBy] = {User}.[Id] -- <-- add join here
#RegexString
#SearchFilter
#CreatedBy
GROUP BY
{Deck}.[Id], {Deck}.[Name], {User}.[Name], -- <-- add column here
{Deck}.[TableOfContentId], {Deck}.[CreatedOn],
{Deck}.[CreatedBy], {Deck}.[LastModifiedOn],
{Deck}.[ExpiryDate], {Deck}.[NumOfPreviews],
{Deck}.[NumOfDownloads], s1.[Count]
ORDER BY #Orderby
You didn't show your tries, so we don't know if there was an error or undesired result. With this form of question that is all I can help. Also USER is one of Oracle Reserved Words, it's better to avoid using it as alias, variable name etc.

The type "geography" is not comparable. It cannot be used in the GROUP BY clause

I have a query like this :
SELECT WorkId,
RegisterDate , Location
FROM (
SELECT dbo.[Work].WorkId ,
dbo.[Work].RegisterDate , dbo.Look.Location
FROM dbo.Municipality INNER JOIN
dbo.[Work] ON dbo.Municipality .Municipality Id = dbo.[Work].MunicipalityWorkId INNER JOIN
dbo.Look ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE (dbo.Look.Location IS NOT NULL) AND Type= 1
) E
GROUP BY WorkId ,RegisterDate , Location
And I get this error :
The type "geography" is not comparable. It cannot be used in the GROUP
BY clause.
I need to add Location to Group By, because I need to display Location in the database. What is the solution for this situation? Thanks.
Here is one way.
Convert the Location to text using Stastext and use it Group by. Then convert it back to geo in Select using STGeomFromText
SELECT WorkId,
RegisterDate,
geography::STGeomFromText(Location.STAsText(), 4326)
FROM (SELECT dbo.[Work].WorkId,
dbo.[Work].RegisterDate,
dbo.Look.Location
FROM dbo.Municipality
INNER JOIN dbo.[Work]
ON dbo.Municipality.MunicipalityId = dbo.[Work].MunicipalityWorkId
INNER JOIN dbo.Look
ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE ( dbo.Look.Location IS NOT NULL )
AND Type = 1) E
GROUP BY WorkId,
RegisterDate,
Location.STAsText()
Referred from this answer
Note : The geography function are CASE sensitive it should be used as it is
STGeomFromText
STAsText
You an not using aggregate function like sum or count so you could avoid group by and order by
SELECT
WorkId
, RegisterDate
, Location
FROM (
SELECT
dbo.[Work].WorkId
, dbo.[Work].RegisterDate
, dbo.Look.Location
FROM dbo.Municipality
INNER JOIN dbo.[Work] ON dbo.Municipality.Municipality Id = dbo.[Work].MunicipalityWorkId
INNER JOIN dbo.Look ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE (dbo.Look.Location IS NOT NULL) AND Type= 1
ORDER BY WorkId ,RegisterDate , Location
) E

SQL Server : Select from two tables with default value 0

Table - BASECASE(CaseNumber, PatientID)
CaseNumber------PatientID
S100---------------P201
S101---------------P201
S102---------------P200
S103---------------P199
S104---------------P201
2nd table
Table - CHECKUP(CheckupNumber, CaseNumber)
CheckupNumber------CaseNumber
C301-------------------S100
C302-------------------S100
C303-------------------S101
C304-------------------S102
C305-------------------S103
SQL Code
SELECT CaseNumber FROM BASECASE
& COUNT(CaseNumber)FROM CHECKUP, WHERE PatientID='P201'
If the CaseNumber is Not present in CHECKUP, COUNT(CaseNumber)[which will be null] should return value 0.
Expected result.
CaseNumber-----No.Of Checkups
S100------------------2
S101------------------1
S104------------------0
How to sort out this problem?
you need to use left join and group by
select B.caseNumber, ISNULL(count(C.checkupNumber) ,0)
from BaseTable B
left join Checkup C
on B.caseNumber = C.caseNumber
where B.patientId ='P201'
group by B.caseNumber
Join with Group BY
select BC.Casenumber,isnull(COUNT(BC.Casenumber),0) CNT from BaseCase BC
left
join CheckUp Ch
on BC.CasetNumber=Ch.CaseNumber
group by BC.Casenumber
You need to use Left Join with Group by
SELECT cn.cno,Count(cp.cno) as NoofCheckup FROM casenumber cn LEFT JOIN checkup cp ON cn.cno=cp.cno
WHERE cn.patientid='P201'
GROUP BY cn.cno

SQL INNER JOIN DISTINCT with max function

I have the tables tbMeasurement and tbPatientMeasurement .
tbMeasurement
MeasurementIDP
MeasurementName
tbPatientMeasurement
PatientMeasurementIDP
MeasurementIDF
MeasurementValue
Taken (Datetime)
When doing the following query:
SELECT DISTINCT dbo.tbMeasurement.MeasurementName
, dbo.tbPatientMeasurement.MeasurementValue
, dbo.tbPatientMeasurement.Taken
FROM dbo.tbMeasurement
INNER JOIN dbo.tbPatientMeasurement
ON dbo.tbMeasurement.MeasurementIDP = dbo.tbPatientMeasurement.MeasurementIDF
This returns a double entry of one of the MeasurementName.
and i also want MeasurementName,MeasurementValue by max Taken(datetime).
Try this one -
SELECT DISTINCT
m.MeasurementName
, p2.MeasurementValue
, p2.Taken
FROM dbo.tbMeasurement m
JOIN (
SELECT
p.MeasurementValue
, Taken = MAX(p.Taken)
FROM dbo.tbPatientMeasurement p
GROUP BY m.MeasurementName, p.MeasurementValue
) p2 ON m.MeasurementIDP = p2.MeasurementIDF
SELECT
m.MeasurementName
, p.MeasurementValue
, a.Taken
FROM dbo.tbMeasurement m
INNER JOIN dbo.tbPatientMeasurement p ON m.MeasurementIDP = p.MeasurementIDF
INNER JOIN
(
select MeasurementIDF,MAX(Taken) as taken
from tbPatientMeasurement
group by MeasurementIDF
) a on a.MeasurementIDF=p.MeasurementIDF and a.taken=p.Taken