how to get both month name and year from field and by w - sql

I have to fetch both month name and year from field in my table but writing below query I am getting an error. Kindly do the needful to rectify my error.
Thanks in advance.
Query:
select SUM(p.Actual_Amount) as buying,
SUM(p.TotalPackageCost) as selling,
(SUM(p.TotalPackageCost) - SUM(p.Actual_Amount)) as profit,
COUNT(e.Enquiry_Id) as Sales,
DATENAME(MM,e.Arrives_On) as Month,
(DATENAME(MONTH,e.Arrives_On) +'-'+ DATENAME(YYYY,e.Arrives_On)) as Date
from Pricing p
inner join Enquiry e on e.Enquiry_Id = p.Enquiry_Id where e.Agent_Name ='Ish Travels' and e.status = 'Confirmed By Company'
group by DATENAME(MM,e.Arrives_On)
order by Month desc
But I am getting the error:
Column 'Enquiry.Arrives_On' is invalid in the select list because it
is not contained in either an aggregate function or the GROUP BY
clause.
Please help me to resolve the error.

Your group by clause is not complete. Every expression in your projection which is not contained in an aggregate function has to be used in group by. I'm pretty sure this is working:
select
SUM(p.Actual_Amount) as buying,
SUM(p.TotalPackageCost) as selling,
(SUM(p.TotalPackageCost) - SUM(p.Actual_Amount)) as profit,
COUNT(e.Enquiry_Id) as Sales,
DATENAME(MM,e.Arrives_On) as Month,
(DATENAME(MONTH,e.Arrives_On) +'-'+ DATENAME(YYYY,e.Arrives_On)) as Date
from
Pricing p inner join Enquiry e on e.Enquiry_Id = p.Enquiry_Id
where
e.Agent_Name ='Ish Travels'
and
e.status = 'Confirmed By Company'
group by
DATENAME(MM,e.Arrives_On),
(DATENAME(MONTH,e.Arrives_On) +'-'+ DATENAME(YYYY,e.Arrives_On))
order by
5 desc

Related

Date field not contained in either an aggregate function or the GROUP BY clause

I am trying to calculate "Month to date" using three joined tables. It always gives me error "not contained in either an aggregate function or the GROUP BY clause" The date field is S.BUS_DAT
I tried many things but always get same error. Any advise
Here is the code I use
SELECT
-- Select from IM_IN
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
--Select from IM_ITEM
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
count (S.BUS_DAT) AS BUS_DAYS,
**sum (QTY_SOLD) OVER (PARTITION BY Month (S.BUS_DAT))as **MTD****
FROM
dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M
ON
N.ITEM_NO = M.ITEM_NO
INNER JOIN
dbo.PS_TKT_HIST_LIN S
ON
N.ITEM_NO = S.ITEM_NO
Group by
M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST
Order by M.ITEM_NO
try to include Month(S.BUS_DAT) into group by as well:
SELECT
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
COUNT(S.BUS_DAT) AS BUS_DAYS,
SUM(QTY_SOLD) OVER(PARTITION BY MONTH(S.BUS_DAT)) AS MTD
FROM dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M ON N.ITEM_NO = M.ITEM_NO
INNER JOIN dbo.PS_TKT_HIST_LIN S ON N.ITEM_NO = S.ITEM_NO
GROUP BY M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST,
MONTH(S.BUS_DAT)
ORDER BY M.ITEM_NO;
I believe you want:
sum(sum(QTY_SOLD)) OVER (PARTITION BY Month(S.BUS_DAT)) as MTD
Note: You will still need month(s.bus_dat) in the group by clause.
If you only want the sum for the current month, then you don't want a window function, just conditional aggregation:
sum(case when year(s.bus_dat) = year(getdate()) and month(s.bus_dat) = month(getdate())
then qty_sold
end) as mtd

Group by 4 different levels and total numeric field

I'm querying a financial database that has the following information:
Company ID
Fiscal Year
Fiscal Period
Account
Amount
I want to group the data by the first four fields and show a grouped total of amount.
I tried the GROUP BY but that doesn't seem to work.
In my screenshot, I'm trying to get rows 1-10 to show as one line, as all the information is the same except for the amount.
Here's my code:
SELECT Erp.GLJrnDtl.Company, Erp.GLJrnDtl.FiscalYear,
Erp.GLJrnDtl.FiscalPeriod, Erp.GLJrnDtl.BalanceAcct,
Erp.GLJrnDtl.BookDebitAmount - Erp.GLJrnDtl.BookCreditAmount AS Amount
FROM Erp.GLJrnDtl INNER JOIN
Erp.GLPeriodBal ON Erp.GLJrnDtl.Company =
Erp.GLPeriodBal.Company AND Erp.GLJrnDtl.FiscalYear =
Erp.GLPeriodBal.FiscalYear AND Erp.GLJrnDtl.FiscalPeriod =
Erp.GLPeriodBal.FiscalPeriod AND
Erp.GLJrnDtl.BalanceAcct =
Erp.GLPeriodBal.BalanceAcct
WHERE (Erp.GLJrnDtl.FiscalYear >= 2018) AND (Erp.GLJrnDtl.Company
= N'011') and (Erp.GLJrnDtl.SegValue1 = N'310050')
GROUP BY Erp.GLJrnDtl.Company, Erp.GLJrnDtl.FiscalYear,
Erp.GLJrnDtl.FiscalPeriod, Erp.GLJrnDtl.BalanceAcct,
Erp.GLJrnDtl.PostedDate, Erp.GLJrnDtl.BookDebitAmount,
Erp.GLJrnDtl.BookCreditAmount, Erp.GLJrnDtl.SegValue1,
Erp.GLPeriodBal.BalanceAmt
select company_id, fiscal_year, fiscal_period, account, sum(amount)
from table group by company_id, fiscal_year, fiscal_period, account
You need to leave out the field you want to aggregate outside the group by line
Please explain why this does not do what you want:
select Company_ID, Fiscal_Year, Fiscal_Period, Account, sum(Amount)
from t
group by Company_ID, Fiscal_Year, Fiscal_Period, Account;
This is the "obvious" query. The query in the image is much more complicated.

Using a date field for matching SQL Query

I'm having a bit of an issue wrapping my head around the logic of this changing dimension. I would like to associate these two tables below. I need to match the Cost - Period fact table to the cost dimension based on the Id and the effective date.
As you can see - if the month and year field is greater than the effective date of its associated Cost dimension, it should adopt that value. Once a new Effective Date is entered into the dimension, it should use that value for any period greater than said date going forward.
EDIT: I apologize for the lack of detail but the Cost Dimension will actually have a unique Index value and the changing fields to reference for the matching would be Resource, Project, Cost. I tried to match the query you provided with my fields, but I'm getting the incorrect output.
FYI: Naming convention change: EngagementId is Id, Resource is ConsultantId, and Project is ProjectId
I've changed the images below and here is my query
,_cte(HoursWorked, HoursBilled, Month, Year, EngagementId, ConsultantId, ConsultantName, ProjectId, ProjectName, ProjectRetainer, RoleId, Role, Rate, ConsultantRetainer, Salary, amount, EffectiveDate)
as
(
select sum(t.Duration), 0, Month(t.StartDate), Year(t.StartDate), t.EngagementId, c.ConsultantId, c.ConsultantName, c.ProjectId, c.ProjectName, c.ProjectRetainer, c.RoleId, c.Role, c.Rate, c.ConsultantRetainer,
c.Salary, 0, c.EffectiveDate
from timesheet t
left join Engagement c on t.EngagementId = c.EngagementId and Month(c.EffectiveDate) = Month(t.EndDate) and Year(c.EffectiveDate) = Year(t.EndDate)
group by Month(t.StartDate), Year(t.StartDate), t.EngagementId, c.ConsultantName, c.ConsultantId, c.ProjectId, c.ProjectName, c.ProjectRetainer, c.RoleId, c.Role, c.Rate, c.ConsultantRetainer,
c.Salary, c.EffectiveDate
)
select * from _cte where EffectiveDate is not null
union
select _cte.HoursWorked, _cte.HoursBilled, _cte.Month, _cte.Year, _cte.EngagementId, _cte.ConsultantId, _cte.ConsultantName, _cte.ProjectId, _Cte.ProjectName, _cte.ProjectRetainer, _cte.RoleId, _cte.Role, sub.Rate, _cte.ConsultantRetainer,_cte.Salary, _cte.amount, sub.EffectiveDate
from _cte
outer apply (
select top 1 EffectiveDate, Rate
from Engagement e
where e.ConsultantId = _cte.ConsultantId and e.ProjectId = _cte.ProjectId and e.RoleId = _cte.RoleId
and Month(e.EffectiveDate) < _cte.Month and Year(e.EffectiveDate) < _cte.Year
order by EffectiveDate desc
) sub
where _cte.EffectiveDate is null
Example:
I'm struggling with writing the query that goes along with this. At first I attempted to partition by greatest date. However, when I executed the join I got the highest effective date for every single period (even those prior to the effective date).
Is this something that can be accomplished in a query or should I be focusing on incremental updates of the destination table so that any effective date / time period in the past is left alone?
Any tips would be great!
Thanks,
Channing
Try this one:
; with _CTE as(
select p.* , c.EffectiveDate, c.Cost
from period p
left join CostDimension c on p.id = c.id and p.Month = DATEPART(month, c.EffectiveDate) and p.year = DATEPART (year, EffectiveDate)
)
select * from _CTE Where EffectiveDate is not null
Union
select _CTE.id, _CTE.Month, _CTE.Year, sub.EffectiveDate, sub.Cost
from _CTE
outer apply (select top 1 EffectiveDate, Cost
from CostDimension as cd
where cd.Id = _CTE.id and cd.EffectiveDate < DATETIMEFROMPARTS(_CTE.Year, _CTE.Month, 1, 0, 0, 0, 0)
order by EffectiveDate desc
) sub
where _Cte.EffectiveDate is null

I want to fetch this data year wise

Select
CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount]
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where
CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01'
Group By
CIDetail.Itemname
Have a derived table where you use ANSI SQL's EXTRACT to get the year part out of the date, and also add the amounts together. At main level you do GROUP BY both Itemname and year:
Select Itemname, "year", SUM(Amount) as TotalAmount
from
(
CIDetail.Itemname,
extract(year from CIHeader.InvoiceDate) as "year",
CIDetail.TaxAmount + CIDetail.LineAmount As Amount
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
) dt
Group By
Itemname, "year"
No dbms tagged in question, but if your dbms doesn't support EXTRACT, try YEAR(CIHeader.InvoiceDate) for example, or something else.
Add to the query a order by clause. Here as you are saying that you want it by date, I will assume that one itemname has only one InvoiceDate. And thus its max will have the same value. You will have to do it as follows
Select CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount],
From CIDetail (Nolock) INNER JOIN CIHeader
On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01' Group By
CIDetail.Itemname
Order By max(CIHeader.InvoiceDate) ASC

Incorrect sum when I join a second table

This is the first time I ask for your help,
Actually I have to create a query, and did a similar example for it. I have two tables,
Report (ReportID, Date, headCount)
Production(ProdID, ReportID, Quantity)
My question is using this query, I get a wrong result,
SELECT
Report.date,
SUM(Report.HeadCount) AS SumHeadCount,
SUM(Production.Quantity) AS SumQuantity
FROM
Report
INNER JOIN
Production ON Report.ReportID = Production.ReportID
GROUP BY
Date
ORDER BY
Date
I guess some rows are being counted more than once, could you please give me a hand?
EDIT
if i run a query to get a sum of headcount grouped by day, I get:
date Headcount
7/2/2012 1843
7/3/2012 1802
7/4/2012 1858
7/5/2012 1904
also for Production Qty I get:
2012-07-02 8362
2012-07-03 8042
2012-07-04 8272
2012-07-05 9227
but when i combine the both queries i get i false one, i expect on 2 july 8362 qty against 1843, but i get:
day TotalHeadcount totalQty
7/2/2012 6021 8362
7/3/2012 7193 8042
7/4/2012 6988 8272
7/5/2012 7197 9227
This may be helpful
SELECT Report.ReportDate,
Sum(Report.HeadCount) AS SumHeadCount,
ProductionSummary.SumQuantity
FROM Report
INNER JOIN (SELECT ReportID,
Sum(Production.Quantity) AS SumQuantity
FROM Production
GROUP BY ReportID) AS ProductionSummary
ON Report.ReportID = ProductionSummary.ReportID
GROUP BY ReportDate
ORDER BY ReportDate
One way of avoiding this (subject to RDBMS support) would be
WITH R
AS (SELECT *,
Sum(HeadCount) OVER (PARTITION BY date) AS SumHeadCount
FROM Report)
SELECT R.date,
SumHeadCount,
Sum(P.Quantity) AS SumQuantity
FROM R
JOIN Production P
ON R.ReportID = P.ReportID
GROUP BY R.date, SumHeadCount
ORDER BY R.date
Group records per date using following
SELECT ReportSummary.ReportDate, SUM(ReportSummary.SumHeadCount) AS SumHeadCount, SUM(ProductionSummary.SumQuantity) AS SumQuantity
FROM
(
SELECT Report.ReportDate, SUM(Report.HeadCount) AS SumHeadCount
FROM Report
GROUP BY Report.ReportDate
) AS ReportSummary
INNER JOIN
(
SELECT Report.ReportDate, Sum(Production.Quantity) AS SumQuantity
FROM Production
INNER JOIN Report
ON Report.ReportID = Production.ReportID
GROUP BY Report.ReportDate
) AS ProductionSummary
ON ReportSummary.ReportDate = ProductionSummary.ReportDate
GROUP BY ReportSummary.ReportDate
ORDER BY ReportSummary.ReportDate
We have same problem but I solved it. Try this.
SELECT tbl_report.SumHeadCount, tbl_report.date, tbl_production.SumQuantity
FROM
( select date,
SUM(HeadCount) AS SumHeadCount FROM Report GROUP by date)as tbl_report
JOIN
( select SUM(Quantity) AS SumQuantity, date FROM Production GROUP by date)as tbl_production
WHERE tbl_report.date = tbl_production.date