Only display the day with the max profit per store - sql

Only display the day with the max profit per store in SQL Server
For example only {Monday 5929.00 DARIEN BRONX GOODS} should only show for DARIEN BRONX GOODS
What I have so far.
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
DIM_D_STORE.STORE_NAME,
[Total Profit] desc
offset 0 rows ;
[Output in image ]

here is one way using window functions:
select * from (
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name],
rank() over (partition by STORE_NAME order by sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) desc) rn
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
) table where rn = 1

Wouldn't Top 1 do the job for selecting highest profit?
select Top 1,
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
[Total Profit] desc,
DIM_D_STORE.STORE_NAME

Related

Invalid subquery, trying to get the customer ID that goes along with the invoice

Here is my SQL, I am trying to get the DISTINCT item ids that have not been invoiced in the past two years that also have a qty on hand greater than 0. I am having an issue getting the last customer id that was invoiced for each distinct item id.
SELECT DISTINCT
im.item_id,
MAX(il.date_created),
(SELECT TOP 1 customer_id
FROM invoice_hdr ih2
WHERE ih.invoice_no = ih2.invoice_no) AS customer_id,
inv_loc.qty_on_hand,
ih.sales_location_id,
MAX(il.commission_cost)
FROM
invoice_hdr ih
INNER JOIN
invoice_line il ON ih.invoice_no = il.invoice_no
INNER JOIN
inv_mast im ON il.inv_mast_uid = im.inv_mast_uid
INNER JOIN
inv_loc ON im.inv_mast_uid = inv_loc.inv_mast_uid
WHERE
inv_loc.qty_on_hand > '0'
GROUP BY
im.item_id, inv_loc.qty_on_hand, ih.sales_location_id
HAVING
(MAX(il.date_created) < DATEADD(year, -2, GETDATE()))
I get this error:
Column 'invoice_hdr.invoice_no' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I understand the error, but no matter what I try I cannot get it to work.
I was able to get the correct data with the following query:
SELECT DISTINCT il.item_id,
ih.customer_id,
il.customer_part_number,
il.date_created,
SUM(inv_loc.qty_on_hand) AS [Qty On Hand],
ih.sales_location_id,
MAX(il.commission_cost) AS [Max Commission Cost]
FROM invoice_hdr ih
JOIN invoice_line il ON ih.invoice_no = il.invoice_no
JOIN inv_loc ON il.inv_mast_uid = inv_loc.inv_mast_uid
WHERE (SELECT TOP 1 il2.date_created FROM invoice_line il2 WHERE il2.item_id = il.item_id ORDER BY il2.date_created DESC) < DATEADD(YEAR, -2, GETDATE())
AND (SELECT TOP 1 il2.invoice_no FROM invoice_line il2 WHERE il2.item_id = il.item_id ORDER BY il2.date_created DESC) = ih.invoice_no
GROUP BY il.item_id,
ih.customer_id,
il.date_created,
ih.sales_location_id,
customer_part_number
HAVING SUM(inv_loc.qty_on_hand) > 0
ORDER BY il.item_id

Multiplying 2 columns in sql but calculation is incorrect?

I have the following select statement:
SELECT c.compname AS [Company]
,e.empname AS [Employee Name]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,x.Ressnavn AS [Client]
,tr.Sale
,SUM(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM job a
INNER JOIN jobplan jp ON jp.JobId = a.jobid
INNER JOIN JobDimensions AS z ON z.jobid = a.jobid
INNER JOIN Ress AS x ON x.RessId = z.custid
INNER JOIN JobPrice AS y ON y.JobId = a.Jobid
INNER JOIN task t ON t.PlanId = jp.PlanId
INNER JOIN JobPriceactivity AS w ON w.priceId = y.priceId
INNER JOIN taskres tr ON tr.TaskId = t.TaskId
INNER JOIN emp e ON e.EmpId = tr.ResId
INNER JOIN comp c ON e.compid = c.compid
INNER JOIN CapUsed AS cu ON cu.RefId = tr.TaskResId
AND cu.RefType = 1
INNER JOIN arpaccount AS ar ON e.empname = ar.arpaccname
AND CAST(cu.DayDate AS DATE) BETWEEN #startdate
AND #enddate
WHERE e.EMPID >= '2'
AND cu.HrsBooked > '0'
GROUP BY c.compname
,e.empname
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,x.Ressnavn
,y.priceid
,tr.Sale
But the calculation of my 'SUM' in the select is not correct as highlighted in yellow in the following extract
I was expecting something like the below highlighted in green:
Can anyone highlight where I am going wrong either in my main code or column sum?

Join results of 3 queries

i have 3 worked queries, but i don't know how to combin them in one query.
TABLES :
------------------ -------------------------- -----------------
PIECE MCARTEFIDENT MCARTEFIDLIG
------------------ -------------------------- -----------------
ET_LIBELLE : Store MFC_ETABLISSEMENT : STORE MFL_ETABLISSEMENT
GP_NUMERO : TICKET MFC_VALDISPOTHEO MFL_NBPASSAGEAPRES
------------------- --------------------------
--QUERY 1
select [et_libelle] AS [STORE NAME],COUNT([GP_NUMERO])
FROM PIECE
LEFT OUTER JOIN ETABLISS ET1 ON gp_etablissement=ET1.ET_ETABLISSEMENT
GROUP BY et_libelle
--QUERY 2
SELECT MFC_ETABLISSEMENT as [STORE NAME], COUNT (MFC_VALDISPOTHEO)
FROM MCARTEFIDENT
LEFT OUTER JOIN ETABLISS ET2 ON MFC_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
GROUP BY MFC_ETABLISSEMENT
--QUERY 3
SELECT MFL_ETABLISSEMENT AS [STORE NAME], MFL_NBPASSAGEAPRES
FROM MCARTEFIDLIG
LEFT OUTER JOIN ETABLISS ET3 ON MFL_ETABLISSEMENT=ET3.ET_ETABLISSEMENT
GROUP BY MFL_ETABLISSEMENT
columns should be the result after combine :
[et_libelle] (Query 1),
COUNT([GP_NUMERO]) (Query 1),
COUNT([GP_NUMERO]) (Query 2),
MFL_NBPASSAGEAPRES (Query 3)
you could use your 3 queries as subqiery and join
select a.[STORE NAME], a.count_gp_numero, b.count_mfc_valdispotheo, c.MFL_NBPASSAGEAPRES
from (
select [et_libelle] AS [STORE NAME], COUNT([GP_NUMERO]) count_gp_numero
FROM PIECE
LEFT OUTER JOIN ETABLISS ET1 ON gp_etablissement=ET1.ET_ETABLISSEMENT
GROUP BY et_libelle
) a
left join (
SELECT MFC_ETABLISSEMENT as [STORE NAME], COUNT(MFC_VALDISPOTHEO) b.count_mfc_valdispotheo
FROM MCARTEFIDENT
LEFT OUTER JOIN ETABLISS ET2 ON MFC_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
GROUP BY MFC_ETABLISSEMENT
) b on a.[STORE NAME] = b.[STORE NAME]
left join (
SELECT MFL_ETABLISSEMENT AS [STORE NAME], MFL_NBPASSAGEAPRES
FROM MCARTEFIDLIG
LEFT OUTER JOIN ETABLISS ET3 ON MFL_ETABLISSEMENT=ET3.ET_ETABLISSEMENT
GROUP BY MFL_ETABLISSEMENT
) c on a.[STORE NAME] = c.[STORE NAME]
If I had to speculate, my guess would be that you want:
select e.*,
(select count(*)
from piece p
where p.gp_etablissement = e.et_etablissement
),
(select count(*)
from MCARTEFIDENT mfc
where mfc.MFC_ETABLISSEMENT = e.et_etablissement
),
(select MFL_NBPASSAGEAPRES -- perhaps a `sum()` here???
from MCARTEFIDENT mfl
where mfl.MFL_ETABLISSEMENT = e.et_etablissement
)
from etabliss e;

Finding the count

I have the following SQL query and need to know the count of companyid as I can see repeating data. How do I find the count of it. Following is the query
SELECT a.companyId 'companyId'
, i.orgDebtType 'orgDebtType'
, d.ratingTypeName 'ratingTypeName'
, c.currentRatingSymbol 'currentRatingSymbol'
, c.ratingStatusIndicator 'ratingStatusIndicator'
, g.qualifierValue 'qualifierValue'
, c.ratingdate 'ratingDate'
, h.value 'outlook'
FROM ciqRatingEntity a
JOIN ciqcompany com
on com.companyId = a.companyId
JOIN ciqratingobjectdetail b ON a.entitySymbolValue = b.objectSymbolValue
JOIN ciqRatingData c ON b.ratingObjectKey = c.ratingObjectKey
JOIN ciqRatingType d ON b.ratingTypeId = d.ratingTypeId
JOIN ciqRatingOrgDebtType i ON i.orgDebtTypeId=b.orgDebtTypeId
JOIN ciqRatingEntityData red ON red.entitySymbolValue=a.entitySymbolValue
AND red.ratingDataItemId='1' ---CoName
LEFT JOIN ciqRatingDataToQualifier f ON f.ratingDataId = c.ratingDataId
LEFT JOIN ciqRatingQualifiervalueType g ON g.qualifiervalueid = f.qualifierValueId
LEFT JOIN ciqRatingValueType h ON h.ratingValueId = c.outlookValueId
WHERE 1=1
AND b.ratingTypeId IN ( '130', '131', '126', '254' )
-- and a.companyId = #companyId
AND a.companyId IN
(SELECT distinct TOP 2000000
c.companyId
FROM ciqCompany c
inner join ciqCompanyStatusType cst on cst.companystatustypeid = c.companystatustypeid
inner join ciqCompanyType ct on ct.companyTypeId = c.companyTypeId
inner join refReportingTemplateType rep on rep.templateTypeId = c.reportingtemplateTypeId
inner join refCountryGeo rcg on c.countryId = rcg.countryId
inner join refState rs on rs.stateId = c.stateId
inner join ciqSimpleIndustry sc on sc.simpleIndustryId = c.simpleIndustryId
ORDER BY companyid desc)
ORDER BY companyId DESC, c.ratingdate, b.ratingTypeId, c.ratingStatusIndicator
This will list where there are duplicate companyID's
SELECT companyId, count(*) as Recs
FROM ciqCompany
GROUP BY ciqCompany
HAVING count(*) > 1
I understand that you wish to add a column to the query with the count of each companyId, you can use COUNT() OVER():
select count(a.companyId) over (partition by a.companyId) as companyCount,
<rest of the columns>
from ciqRatingEntity a
join <rest of the query>
This would return in each row the count of the companyId of that row without grouping the results.

How to pick Max value of SQL Output

SQL Query Syntax issue. I have a query which returns around 150,000 rows of records. In this query, you can see ROW_NUMBER() OVER PARTITION. On select * from cte, I need to pick only the highest value of ROW_NUMBER() for each Pat_id.
If RowNumber is 150 for one pat_id. I need only that row of records. I am having difficult in narrowing down to one record. I request experts to share your syntax to help me.
with cte
as (
select pat.pat_id,
pat.fname as [FirstName],
pat.mname as [MiddleName],
pat.lname as [LastName],
[DOB] =Convert(VARCHAR(12),pat.birth_date,101),
csc.name as [AccountType],
[Plan Name] = CASE when (isnull(org.name,'')='') then 'CASH' else org.name end
,cprx_disp.disp_days_supply
,cprx_disp.dispense_date
,(cprx_disp.dispense_date + cprx_disp.disp_days_supply) as [DateDue]
,ROW_NUMBER() over(PARTITION BY pat.pat_id ORDER BY cprx_disp.dispense_date) as [RowNumber]
From cppat pat (nolock)
left outer join cppat_ins patins(NoLock) ON patins.pat_id = pat.pat_id
left outer join csorg org on org.org_id = patins.org_id
inner join csct_code csc on pat.pat_type_cn = csc.code_num
join cprx on cprx.pat_id = pat.pat_id
join cprx_disp (nolock) on cprx.last_rxdisp_id = cprx_disp.rxdisp_id
where csc.ct_id = 163
and csc.code_num in (1033,1010,1011,1012,1016,1017,1016,1018)
and patins.status_cn = 1
and patins.priority = 1
-- Commented.
-- and pat.pat_id = 2561
)
select cte.[FirstName],
cte.[MiddleName],
cte.[LastName],
cte.[DOB],
cte.[AccountType],
cte.[Plan Name],
Cte.DateDue
from cte
Well, you're not actually using the RowNumber in the output, so I would just reverse it and then return those that equal 1:
with cte
as (
select pat.pat_id,
pat.fname as [FirstName],
pat.mname as [MiddleName],
pat.lname as [LastName],
[DOB] =Convert(VARCHAR(12),pat.birth_date,101),
csc.name as [AccountType],
[Plan Name] = CASE when (isnull(org.name,'')='') then 'CASH' else org.name end
,cprx_disp.disp_days_supply
,cprx_disp.dispense_date
,(cprx_disp.dispense_date + cprx_disp.disp_days_supply) as [DateDue]
,ROW_NUMBER() over(PARTITION BY pat.pat_id ORDER BY cprx_disp.dispense_date DESC) as [RowNumber]
from cppat pat (nolock)
left outer join cppat_ins patins(NoLock) on patins.pat_id = pat.pat_id
left outer join csorg org on org.org_id = patins.org_id
inner join csct_code csc on pat.pat_type_cn = csc.code_num
join cprx on cprx.pat_id = pat.pat_id
join cprx_disp (nolock) on cprx.last_rxdisp_id = cprx_disp.rxdisp_id
where csc.ct_id = 163
and csc.code_num in (1033,1010,1011,1012,1016,1017,1016,1018)
and patins.status_cn = 1
and patins.priority = 1
-- Commented.
-- and pat.pat_id = 2561
)
select cte.[FirstName],
cte.[MiddleName],
cte.[LastName],
cte.[DOB],
cte.[AccountType],
cte.[Plan Name],
cte.DateDue
from cte
WHERE RowNumber = 1;