How do I pivot this SQL result? - sql-server

Whats the best way to PIVOT this SQL result? I was wondering if the count(*) can be done as part of the pivot instead of having to group the data prior?
SELECT
e.fullname,
e.BusinessUnit,
COUNT(*) as total
FROM EmpComplaints e
WHERE e.BusinessUnit in ('1-Sales', '2-Tech', '3-Marketing')
GROUP BY e.fullname, e.BusinessUnit
order by e.fullname, e.BusinessUnit
I am basically reporting on each employee the amount of reports they have in each of the three business units: sales, tech, marketing. and looking to get a result that will list fullnames on the left with each name appearing once and each name having a column for ('1-Sales', '2-Tech', '3-Marketing') with a number in it that would be the count(*)

Is this MS SQL Server? This might work, sorry, don't have it running, so can't verify:
select fullname,
sum(case BusinessUnit when '1-Sales' then 1 else 0 end) as Sales,
sum(case BusinessUnit when '2-Tech' then 1 else 0 end) as Tech,
sum(case BusinessUnit when '3-Marketing' then 1 else 0 end) as Marketing
FROM EmpComplaints
GROUP BY fullname;

Here is how to do it in SQL Server 2005/2008:
SELECT
FullName
,[1-Sales]
,[2-Tech]
,[3-Marketing]
FROM
(
SELECT
e.fullname,
e.BusinessUnit,
COUNT(*) AS Total
FROM EmpComplaints e
WHERE e.BusinessUnit in ('1-Sales', '2-Tech', '3-Marketing')
GROUP BY e.fullname,e.BusinessUnit
) AS bu
PIVOT
(
SUM(Total)
FOR BusinessUnit IN ([1-Sales], [2-Tech], [3-Marketing])
) AS pvt
ORDER by fullname

Related

Group by two columns with case query in SQL Server

I'm trying to retrieve drivers data with Total Accepted and Total Ignored ride requests for the current date.
Based on the Drivers and DriverReceivedRequests tables, I get the total count but the twists is I have duplicate rows that reside on the DriverReceivedRequest table against the driverId and the rideId. So there has to be group by clause on both the driverId and RideId, having the driver getting multiple requests for the current date, but also receiving twice or thrice request for the same ride as well.
This is the table structure for DriverReceivedRequests:
Id DriverId RideId ReceivedStatusId DateTime
------------------------------------------------------------------------
0014d26b 93665f55 fef6fb96 NULL 04:55.6
00175c65 6e62a94e cb214a84 NULL 09:32.1
0017c22b ec9e1297 4b47dc8a 4211357D 10:28:5
0014d26b 6e62a94e fef6fb96 NULL 04:56.8
This is the query I have tried:
select
d.Id, d.FirstName, d.LastName,
Sum(case when drrs.Number = 1 then 1 else 0 end) as TotalAccepted,
Sum(case when drrs.Number = 2 or drr.ReceivedStatusId is null then 1 else 0 end) as TotalRejected
from
dbo.[DriverReceivedRequests] drr
inner join
dbo.[Drivers] d on drr.DriverId = d.Id
left join
dbo.[DriverReceivedRequestsStatus] drrs on drr.ReceivedStatusId = drrs.Id
where
Day(drr.Datetime) = Day(getdate())
and month(drr.DateTime) = Month(getdate())
group by
d.FirstName, d.LastName, d.Id
In the above query if I group by with RideId as well, it generates duplicate names of drivers as well with incorrect data. I've also applied partition by clause with DriverId but not the correct result
This also generates the same result
WITH cte AS
(
SELECT
d.Id,
d.FirstName, d.LastName,
TotalAccepted = SUM (CASE WHEN drrs.Number = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY drr.DriverId),
TotalRejected = SUM (CASE WHEN drrs.Number = 2 OR drr.ReceivedStatusId IS NULL THEN 1 ELSE 0 END)
OVER (PARTITION BY drr.DriverId),
rn = ROW_NUMBER() OVER(PARTITION BY drr.DriverId
ORDER BY drr.DateTime DESC)
FROM
DriverReceivedRequests drr
INNER JOIN
dbo.[Drivers] d ON drr.DriverId = d.Id
LEFT JOIN
dbo.[DriverReceivedRequestsStatus] drrs ON drr.ReceivedStatusId = drrs.Id
WHERE
DAY (drr.Datetime) = DAY (GETDATE())
AND MONTH (drr.DateTime) = MONTH (GETDATE())
)
SELECT
Id,
FirstName, LastName,
TotalAccepted, TotalRejected
FROM
cte
WHERE
rn = 1
My question is how can I group by individual driver data in terms of incoming ride requests?
Note: the driver receives same ride request multiple times

Microsoft SQL Query‏ return repeated rows in one row

I need your help for this query:
SELECT
'ABBOTT' AS Customername, 'DaleelMAMA' AS AccountName,
dbo.AccountBase.Name AS FullName,
dbo.AccountBase.Telephone1 AS MobilePhone,
dbo.AccountBase.new_HomePhone1 AS HomePhone,
dbo.new_otherparentinformationBase.new_MobilePhone AS ParentPhone,
dbo.AccountBase.new_preferredlanguagetext AS Language
FROM
dbo.AccountBase
LEFT OUTER JOIN
dbo.new_otherparentinformationBase ON dbo.AccountBase.AccountId =
dbo.new_otherparentinformationBase.new_MotherName_lookup
This query returns this result set:
The original result
ABBOTT DaleelMAMA Eman 55555555 NULL 56545412 Arabic
ABBOTT DaleelMAMA Eman 55555555 NULL 22222222 Arabic
ABBOTT DaleelMAMA Eman 55555555 NULL 25456552 Arabic
ABBOTT DaleelMAMA Hala 55552504 22252128 NULL Arabic
but I need to update my query to return this result but as below, if u see u will find that Eman row repeated three time and this because its include different parent phone numbers, so i need to make this result in one row include the mother number and its related parent phones numbers.
required result
please see above link for required result that aim looking about it, thanks for your support in advance.
whole solution look
If it always 4 ParentPhone per Name then try something like this
;with cte as
(
SELECT
'ABBOTT' AS Customername,
'DaleelMAMA' AS AccountName,
ROW_NUMBER() over(partition by dbo.AccountBase.Name order by dbo.AccountBase.Telephone1) as rn,
dbo.AccountBase.Name AS FullName,
dbo.AccountBase.Telephone1 AS MobilePhone,
dbo.AccountBase.new_HomePhone1 AS HomePhone,
dbo.new_otherparentinformationBase.new_MobilePhone AS ParentPhone,
dbo.AccountBase.new_preferredlanguagetext AS Language
FROM
dbo.AccountBase
LEFT OUTER JOIN
dbo.new_otherparentinformationBase ON dbo.AccountBase.AccountId = dbo.new_otherparentinformationBase.new_MotherName_lookup
)
SELECT Customername,
AccountName,
FullName,
MobilePhone,
Max(CASE WHEN rn = 1 THEN ParentPhone END) AS ParentPhone1,
Max(CASE WHEN rn = 2 THEN ParentPhone END) AS ParentPhone2,
Max(CASE WHEN rn = 3 THEN ParentPhone END) AS ParentPhone3,
Max(CASE WHEN rn = 4 THEN ParentPhone END) AS ParentPhone4,
Language
FROM cte
GROUP BY Customername,
AccountName,
FullName,
MobilePhone,
Language
Note : If number of ParentPhone per Name is unknown then you need to use Dynamic pivot. Also start using alias name to make the query more readable

TSQL Partitioning to COUNT() only subset of rows

I have a query that I am working on that, for every given month and year in a sales table, returns back a SUM() of the total items ordered as well as a count of the distinct number of accounts ordering items and a couple break down of SUm()s on various product types. See the query below for an example:
SELECT
YearReported,
MonthReported,
COUNT(DISTINCT DiamondId) as Accounts,
SUM(Quantity) as TotalUnitsOrdered,
SUM(CASE P.ProductType WHEN 1 THEN Quantity ELSE 0 END) as MonthliesOrdered,
SUM(CASE P.ProductType WHEN 1 THEN 0 ELSE Quantity END) as TPBOrdered
FROM
RetailOrders R WITH (NOLOCK)
LEFT JOIN
Products P WITH (NOLOCK) ON R.ProductId = P.ProductId
GROUP BY
YearReported, MonthReported
The problem I am facing now is that I also need to get the count of distinct accounts broken out based on another field in the dataset. For example:
SELECT
YearReported,
MonthReported,
COUNT(DISTINCT DiamondId) as Accounts,
SUM(Quantity) as TotalUnitsOrdered,
SUM(CASE P.ProductType WHEN 1 THEN Quantity ELSE 0 END) as MonthliesOrdered,
SUM(CASE P.ProductType WHEN 1 THEN 0 ELSE Quantity END) as TPBOrdered,
SUM(CASE IsInitial WHEN 1 THEN Quantity ELSE 0 END) as InitialOrders,
SUM(CASE IsInitial WHEN 0 THEN Quantity ELSE 0 END) as Reorders,
COUNT(/*DISTINCT DiamndId WHERE IsInitial = 1 */) as InitialOrderAccounts
FROM
RetailOrders R WITH (NOLOCK)
LEFT JOIN
Products P WITH (NOLOCK) ON R.ProductId = P.ProductId
GROUP BY
YearReported, MonthReported
Obviously we would replace the commented out section in the last SUM with something that would not throw an error. I just added that for illustrative purposes.
I feel like this can be done using the Partition methods in SQL, but I have to admit that I just am not very good with them and cant figure out how to do this. And the MS documentation online for Partitions really just makes my head hurt after reading it last night.
EDIT: I mistakenly has the last aggregate function as sum and I meant for it to be a COUNT().
So to help clarify, COUNT(DISTINCT DiamondId) will give me back a count of all unique DiamondId values in the set but I also need to get a COUNT() of all Unique Diamond Id values in the set whose corresponding IsInitial flag is set to 1
Just a matter of nulling the ones that don't qualify:
count(distinct
case
when IsInitial = 1 then DiamndId
/* else null */
end
)

How to pivot and get total amount each month

I have data like :
My table
My final results should be like this:
My SQL Statement:
SELECT 'Q'+cast([Month_Quarter] as varchar) Month_Quarter,COALESCE([Zugänge],0) Zugänge,COALESCE([Abgänge],0) Abgänge
FROM
(
SELECT DATEPART(QUARTER,[Monat]) [Month_Quarter],
[Zu-, Abgang],
Count(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
GROUP BY DATEPART(QUARTER,[Monat]), [Zu-, Abgang]
) proj
PIVOT (SUM(NoProjects) FOR [Zu-, Abgang] IN (Zugänge, Abgänge)) As pvt
WHERE [Month_Quarter] is not null
ORDER BY Month_Quarter
BUT with this statement I am getting the results without the Amount column Zugang and column Abgang:
How can I edit the statement to get the aggregation amount columns?
I suppose you can just wrap your query inside another select statement, then use GROUP BY. Something like this:
SELECT Month, SUM(ISNULL(column_name,0))
FROM (Your Query in here)
GROUP BY Month
Not sure I understand the point of the PIVOT in your original query. This looks like a typical aggregate is all that is required. See if this is what you need.
SELECT DATENAME(MONTH,Monat) [Month]
, sum(case when [Zu-, Abgang] = 'Zugänge' then [Zu-, Abgang] else 0 end) as Zugänge
, SUM(case when [Zu-, Abgang] = 'Abgänge' then [Zu-, Abgang] else 0 end) as Abgänge
, SUM([GWU aktuell]) as [GWU Total]
, SUM([GWU Planung aktuell]) AS [Plan Total]
, COUNT(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
group by DATENAME(MONTH,Monat)

SQL Percentage calculation

Is it possible in SQL to calculate the percentage of the 'StaffEntered' column's "Yes" values (case when calculated column) out of the grand total number of orders by that user (RequestedBy)? I'm basically doing this function now myself in Excel with a Pivot table, but thought it may be easier to build it into the query. Here is the existing sample SQL code:
Select
Distinct
RequestedBy = HStaff.Name,
AccountID = isnull(pv.AccountID, ''),
StaffEntered = Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end
FROM
[dbo].[HOrd] HOrd WITH ( NOLOCK )
left outer join HStaff HStaff with (nolock)
on HOrd.Requestedby_oid = HStaff.ObjectID
and HStaff.Active = 1
left outer join DictionaryItem DictionaryItem2 WITH (NOLOCK)
ON HSUser1.PreferenceGroup_oid = DictionaryItem2.ObjectID
AND DictionaryItem2.ItemType_oid = 98
Here is what I am doing in Excel currently with the query results, I have a pivot table and I am dividing the "Yes" values of the "StaffEntered" field out of the Grand Total number of entries for that specific "RequestedBy" user. Essentially Excel is doing the summarization and then I am doing a simple division calculation to obtain the percentage.
Thanks in advance!
You didn't provide a lot in the way of details but I think this should be pretty close to what you are looking for.
select HStaff.Name as RequestedBy
, isnull(pv.AccountID, '') as AccountID
, Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end as StaffEntered
, sum(Case When DictionaryItem2.Name like '%PLB%' Then 1 Else 0 end) / GrandTotal
From SomeTable
group by HStaff.Name
, isnull(pv.AccountID, '')
, GrandTotal
Giving the FROM part of your SQL Statement would allow us to create a more correct answer. This statement will get the totals of yes/no per HStaff name and add it to each detail record in your SQL statement:
WITH cte
AS ( SELECT HStaff.Name ,
SUM(CASE WHEN dictionaryItem2.Name LIKE '%PLB%' THEN 1
ELSE 0
END) AS YesCount ,
SUM(CASE WHEN dictionaryItem2.Name NOT LIKE '%PLB%'
THEN 1
ELSE 0
END) AS NotCount
FROM YourTable
GROUP BY HStaff.Name
)
SELECT HStaff.Name AS requestedBy ,
ISNULL(pv.AccountID, '') AS AccountID ,
CASE WHEN DictionaryItem2.Name LIKE '%PLB%' THEN 'Yes'
ELSE 'No'
END AS StaffEntered ,
cte.YesCount / ( cte.YesCount + cte.NotCount ) AS PLB_Percentage
FROM yourtable
INNER JOIN cte ON yourtable.Hstaff.Name = cte.NAME

Resources