SQL Server How to Utilize Pivot in this difficult situation - sql-server

I've been reading a lot of posts on here trying to figure out how to use this pivot function and have not had any luck. Either some of the explanations included something unnecessary to me or made it too difficult for to understand because I only recently started teaching myself SQL.
I need to figure out how to Group my dates into one if possible and turn P1, P2, P3... into columns. Making P1-10 into their each individual column is what is most important.
This is what the original SQL Server looks like.. + many other columns that are irrelevant for what I'm trying to do.
+-------------+------------+---------------------+
| StationName | Start_Time | Time |
+-------------+------------+---------------------+
| P1 | 15 | 2018-06-21 13:37:34 |
+-------------+------------+---------------------+
| P3 | 69 | 2018-06-21 12:33:55 |
+-------------+------------+---------------------+
| P4 | 52 | 2018-06-21 13:42:34 |
+-------------+------------+---------------------+
| P1 | 18 | 2018-06-21 10:37:34 |
+-------------+------------+---------------------+
| P9 | 78 | 2018-06-21 6:37:34 |
+-------------+------------+---------------------+
This is what I currently have
SELECT Cast(Start_Time AS DATE) AS Date,
StationName,
sum(time) AS "Daily Downtime"
FROM A6K_Events
Where StationName Like 'P%'
GROUP BY Cast(Start_Time AS DATE), StationName
Order By Date DESC
+------------+-------------+----------------+
| Date | StationName | Daily Downtime |
+------------+-------------+----------------+
| 2018-06-21 | P1 | 33 |
+------------+-------------+----------------+
| 2018-06-21 | P3 | 62 |
+------------+-------------+----------------+
| 2018-06-21 | P8 | 1 |
+------------+-------------+----------------+
| 2018-06-21 | P9 | 78 |
+------------+-------------+----------------+
| 2018-06-20 | P1 | 69 |
+------------+-------------+----------------+
| 2018-06-19 | P1 | 52 |
+------------+-------------+----------------+
This is what I would like to have:
+------------+----+----+----+----+----+----+----+----+----+-----+
| Date | P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 | P10 |
+------------+----+----+----+----+----+----+----+----+----+-----+
| 2018-06-21 | 33 | | 62 | | | | | 1 | 78 | |
+------------+----+----+----+----+----+----+----+----+----+-----+
| 2018-06-20 | 69 | | | | | | | | | |
+------------+----+----+----+----+----+----+----+----+----+-----+
| 2018-06-19 | 52 | | | | | | | | | |
+------------+----+----+----+----+----+----+----+----+----+-----+
The Numbers filled in would be the Daily Downtime value for that process that day. The end result will be recorded live and contain many dates and various down times.
Thanks for the Help in advance
Edited to add text tables and removed images

You can accomplish the output with the following pivot statement.
SELECT * FROM(
SELECT CAST([Start_Date] AS DATE) as [DATE],SUM(TIME) AS [Daily DownTime],STATIONNAME FROM A6K_Events Where StationName Like 'P%' GROUP BY [start_date],STATIONNAME
) AS S
PIVOT(sum([Daily DownTime]) FOR STATIONNAME IN([P1],[P2],[P3],[P4],[P5],[P6],[P7],[P8],[P9],[P10])) AS PT
http://rextester.com/BAXY34111

Related

Pivoting a table with multiple columns in SQL

My goal here is to take a list of two corresponding store numbers and provide an output similar to:
Ultimate goal: produce a list of closest stores by travel time and distance based on source data of 2 rows per zip9 where each row is the travel time in distance, and in time, to a store in question.
The result is that each zip code has 2 stores to choose from, and the requirement is being able to return one row with both options.
+-----------+---------------+---------------------+-------------------+-------------------------+
| zip | Shortest_time | Shortest_time_store | Shortest_distance | Shortest_distance_store |
+-----------+---------------+---------------------+-------------------+-------------------------+
| 70011134 | 38.7035 | 75 | 21.3124 | 115 |
| 70011186 | 38.4841 | 75 | 21.4144 | 115 |
| 70011207 | 39.1567 | 75 | 21.1826 | 115 |
| 100013232 | 22.976 | 145 | 9.5031 | 115 |
| 112075140 | 21.888 | 145 | 7.3705 | 115 |
+-----------+---------------+---------------------+-------------------+-------------------------+
Original dataset
+---------------+--------------------------+-----------------------+------------------+
| CORRECTED_ZIP | SourceOrganizationNumber | Travel Time (Minutes) | Distance (Miles) |
+---------------+--------------------------+-----------------------+------------------+
| 70011134 | 75 | 38.7035 | 26.8628 |
| 70011134 | 115 | 39.3969 | 21.3124 |
| 70011186 | 75 | 38.4841 | 26.7609 |
| 70011186 | 115 | 39.6389 | 21.4144 |
| 70011207 | 75 | 39.1567 | 31.2771 |
| 70011207 | 115 | 39.188 | 21.1826 |
| 100013232 | 115 | 28.6561 | 9.50311 |
| 100013232 | 145 | 22.976 | 10.0307 |
| 112075140 | 115 | 36.1803 | 7.37053 |
| 112075140 | 145 | 21.888 | 9.50123 |
+---------------+--------------------------+-----------------------+------------------+
Dataset after I've modified it with this query:
SELECT TOP 1000 [corrected_zip]
, TRY_CONVERT( DECIMAL(18, 4), ROUND([Travel Time (Minutes)], 4)) AS [Unit of Measurement]
, [SourceOrganizationNumber]
, 'Time' AS [Type]
FROM [db].[dbo].[my_table_A] [tt]
WHERE [tt].[CORRECTED_ZIP] IN('070011134', '070011186', '070011207', '112075140', '100013232')
AND [Travel Time (Minutes)] IN
(
SELECT MIN([Travel Time (Minutes)])
FROM [db].[dbo].[my_table_A]
WHERE [CORRECTED_ZIP] = [tt].[CORRECTED_ZIP]
GROUP BY [CORRECTED_ZIP]
)
UNION ALL
SELECT TOP 1000 [corrected_zip]
, TRY_CONVERT( DECIMAL(18, 4), ROUND([Distance (Miles)], 4))
, [SourceOrganizationNumber]
, 'Distance'
FROM [db].[dbo].[my_table_A] [tt]
WHERE [tt].[CORRECTED_ZIP] IN('070011134', '070011186', '070011207', '112075140', '100013232')
AND [Distance (Miles)] IN
(
SELECT MIN([Distance (Miles)])
FROM [db].[dbo].[my_table_A]
WHERE [CORRECTED_ZIP] = [tt].[CORRECTED_ZIP]
GROUP BY [CORRECTED_ZIP]
)
ORDER BY [CORRECTED_ZIP];
+---------------+---------------------+--------------------------+----------+
| corrected_zip | Unit of Measurement | SourceOrganizationNumber | Type |
+---------------+---------------------+--------------------------+----------+
| 70011134 | 38.7035 | 75 | Time |
| 70011134 | 21.3124 | 115 | Distance |
| 70011186 | 21.4144 | 115 | Distance |
| 70011186 | 38.4841 | 75 | Time |
| 70011207 | 39.1567 | 75 | Time |
| 70011207 | 21.1826 | 115 | Distance |
| 100013232 | 9.5031 | 115 | Distance |
| 100013232 | 22.976 | 145 | Time |
| 112075140 | 21.888 | 145 | Time |
| 112075140 | 7.3705 | 115 | Distance |
+---------------+---------------------+--------------------------+----------+
Data after I attempted to pivot it
+---------------+--------------------------+----------+---------+
| corrected_zip | SourceOrganizationNumber | Distance | Time |
+---------------+--------------------------+----------+---------+
| 070011134 | 115 | 21.3124 | NULL |
| 070011134 | 75 | NULL | 38.7035 |
| 070011186 | 115 | 21.4144 | NULL |
| 070011186 | 75 | NULL | 38.4841 |
| 070011207 | 115 | 21.1826 | NULL |
| 070011207 | 75 | NULL | 39.1567 |
| 100013232 | 115 | 9.5031 | NULL |
| 100013232 | 145 | NULL | 22.9760 |
| 112075140 | 115 | 7.3705 | NULL |
| 112075140 | 145 | NULL | 21.8880 |
+---------------+--------------------------+----------+---------+
It seems like my issue is picking the correct store ID as opposed to grouping by store ID?
You can use row_number() twice in a subquery(once to rank by time, another by distance), and then do conditional aggregation in the outer query:
select
corrected_zip,
min(travel_time) shortest_time,
min(case when rnt = 1 then source_organization_number end) shortest_time_store,
min(distance) shortest_distance,
min(case when rnd = 1 then source_organization_number end) shortest_distance_store
from (
select
t.*,
row_number() over(partition by corrected_zip order by travel_time) rnt,
row_number() over(partition by corrected_zip order by distance) rnd
from mytable t
) t
group by corrected_zip

Can recursion start from a specific record in a table?

I'm trying to calculate depreciation on vehicles. If there is a rebate on a vehicle, I need to stop the depreciation, factor in the rebaste based on the month it look affect, and resume the depreciation calculation.
A vehicle depreciates at a flat rate of 2% every month with 50 months being the point of 100% depreciation. When a rebate appears, I can stop the depreciation, but I don't know how to make it start again from a certain month.
Below is an example of the table's deprecation up to directly before the rebate:
+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate | Initial Cost | Monthlydep | totaldep |
+----------+-------+------------+--------------+------------+------------+
| 12451 | 1 | 2015-08-01 | 44953.24 | 899.06 | 899.0648 |
| 12451 | 2 | 2015-09-01 | 44953.24 | 899.06 | 1798.1296 |
| ------- | ----- | ----- | ----- | ----- | ----- |
| 12451 | 42 | 2019-01-01 | 44953.24 | 899.06 | 37760.7216 |
| 12451 | 43 | 2019-02-01 | 44953.24 | 899.06 | 38659.7864 |
+----------+-------+------------+--------------+------------+------------+
Then let's say that a rebate comes in this month (2019-03-01) it needs to be factored in and then the depreciation needs to be recalculated from that month onwards the. How do I restart the depreciation from month 43 instead of it going through everything?
For example let's say that we get a rebate in month 44 for $200 dollars. The table should look like something below:
+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate | Initial Cost | Monthlydep | totaldep |
+----------+-------+------------+--------------+------------+------------+
| 12451 | 43 | 2019-02-01 | 44953.24 | 899.06 | 38659.7864 |
| 12451 | 44 | 2019-03-01 | 44953.24 | 1099.06 | 39758.8464 |
| 12451 | 45 | 2019-04-01 | 44953.24 | 1099.06 | 40857.9064 |
| 12451 | 46 | 2019-05-01 | 44953.24 | 1099.06 | 41956.9664 |
| 12451 | 47 | 2019-06-01 | 44953.24 | 1099.06 | 43056.0264 |
| 12451 | 48 | 2019-06-01 | 44953.24 | 1099.06 | 44155.0864 |
| 12451 | 49 | 2019-06-01 | 44953.24 | 1099.06 | 45254.1464 |
+----------+-------+------------+--------------+------------+------------+
So month 49 would be the final month because the totalDep is equal to or higher than the initial cost
My sample code is below. If you remove the first cte and the join inner join in the top part of the union then that is the working depreciation calculation:
;With cte As( Select bd.[VehicleID]
,Max(bd.[Month]) As month
,Max(DateAdd(DAY,1,EOMONTH(DepreciationReportDate,-1))) As DepreciationReportDate
,Max(bd.MonthlyDepreciation) As MonthlyDepreciation
,Max(bd.AdjustedPurchaseCost) As AdjustedPurchaseCost
,Max(AccumulatedDepreciation) As AccumulatedDepreciation
From Work.dbo.DepreciationSchedule bd
Group By bd.VehicleID
)
,cte_CreateRows As
(
Select bd.[VehicleID]
,bd.[Month]
,DATEADD(DAY,1,EOMONTH(bd.DepreciationReportDate,-1)) As DepreciationReportDate
,bd.MonthlyDepreciation
,bd.AdjustedPurchaseCost
,bd.AccumulatedDepreciation
From Work.dbo.DepreciationSchedule bd
Inner Join cte cte
On cte.VehicleID = bd.VehicleID
And cte.month = bd.Month
Union All
Select bd.[VehicleID]
,[Month] = Cast(cr.[Month]+1 As int)
,DATEADD(DAY,1,EOMONTH(DateAdd(Month, 1, cr.DepreciationReportDate),-1)) As DepreciationReportDate
,bd.MonthlyDepreciation
,bd.AdjustedPurchaseCost
,AccumulatedDepreciation = cr.AccumulatedDepreciation + cr.MonthlyDepreciation
From Work.dbo.DepreciationSchedule bd
Inner Join cte_CreateRows cr On bd.[VehicleID] = cr.[VehicleID]
Where cr.AccumulatedDepreciation < cr.AdjustedPurchaseCost
And DateAdd(Month,1, DateAdd(DAY,1,EOMONTH(cr.DepreciationReportDate,-1))) < DATEADD(DAY,1,EOMONTH(GetDate(),-1))
)
Select a.VehicleID
,a.Month
,a.DepreciationReportDate
,Cast(a.MonthlyDepreciation As Decimal(12,2)) As 'Monthly Depreciation Expense'
,a.AdjustedPurchaseCost
,a.AccumulatedDepreciation
From [cte_CreateRows] As a
Order By a.VehicleID, a.Month

SQL Server Query - How to Pivot this set of data

I've been playing around and just not coming up with anything workable :( I have a simple query:
SELECT DISTINCT IP.DeviceUID, IP.DeviceName, d.NodeName from Devices d
inner join IPSCHEMA IP on IP.PLCIP=d.CommunicationAddress
This brings me to the data I want to Pivot (Subset of that data below):
|---------------------|------------------|------------------|
| DeviceUID | DeviceName | NodeName |
|---------------------|------------------|------------------|
| 226 | Boiler | BOILER |
|---------------------|------------------|------------------|
| 226 | Boiler | AMMONIA |
|---------------------|------------------|------------------|
| 226 | Boiler | CHILLER |
|---------------------|------------------|------------------|
| 230 | SSilo | SSUG |
|---------------------|------------------|------------------|
| 230 | SSilo | WALKER |
|---------------------|------------------|------------------|
| 29 | Cooling | AMMONIA |
|---------------------|------------------|------------------|
| 29 | Cooling | BOILER |
|---------------------|------------------|------------------|
| 29 | Cooling | CAR_A |
|---------------------|------------------|------------------|
| 29 | Cooling | CAR_B |
|---------------------|------------------|------------------|
| 29 | Cooling | LINE1 |
|---------------------|------------------|------------------|
I need it to look like the following:
|---------------------|------------------|------------------|------------------|------------------|------------------|------------------|
| DeviceUID | DeviceName | Node1 | Node2 | Node3 | Node 4 | Node5 |
|---------------------|------------------|------------------|------------------|------------------|------------------|------------------|
| 226 | Boiler | BOILER | AMMONIA | CHILLER | | |
|---------------------|------------------|------------------|------------------|------------------|------------------|------------------|
| 230 | SSilo | SSUG | WALKER | | | |
|---------------------|------------------|------------------|------------------|------------------|------------------|------------------|
| 29 | Cooling | AMMONIA | BOILER | CAR_A | CAR_B | LINE1 |
|---------------------|------------------|------------------|------------------|------------------|------------------|------------------|
I'm sure I can export to Excel, modify, make it look like that. But I would like this to be a repeatable Stored Procedure I can use for the current dataset.
Thanks in advance.
Untested, but we just add a PIVOT to your initial query.
This also assumes you have a known or maximum number of nodes. If not, you would have to go DYNAMIC.
Select *
From (
Select *
,Item = concat('Node',Row_Number() over (Partition By DeviceUID,DeviceName Order by (Select null))
From (
SELECT DISTINCT IP.DeviceUID, IP.DeviceName, d.NodeName from Devices d
inner join IPSCHEMA IP on IP.PLCIP=d.CommunicationAddress
) A
) src
Pivot (max(NodeName) for Item in ([Node1],[Node2],[Node3],[Node4],[Node5]) ) pvt

get all rows where column value is same in cassandra cql

This is my table.
cqlsh:sachhya> select * FROM emp;
emp_id | age | emp_name | exp | mobile
--------+-----+--------------+-----+------------
5 | 29 | RAHUL SHARMA | 9 | 2312343123
1 | 24 | SACHHYA | 15 | 9090987876
2 | 14 | SACHHYA | 15 | 9090987876
4 | 22 | ANKUR | 32 | 3213456321
90 | 30 | sumeet | 2 | 91234212
3 | 14 | SACHHYA | 3 | 9090987876
PRIMARY KEY (Partition key) IS emp_id.
I want to display all rows where emp_name is 'SACHHYA'. What command should i use?
Below is the cql query that i am using.
select * FROM emp WHERE emp_name='SACHHYA';
But i am getting an error:
InvalidRequest: Error from server: code=2200 [Invalid query]
message="Predicates on non-primary-key columns (emp_name) are not yet
supported for non secondary index queries"
I have found one solution for my question, We can crate index on 'emp_name' column after that we can use 'emp_name' filter.
EX:
CREATE INDEX NameIndx ON emp (emp_name);
SELECT * from sachhya.emp WHERE emp_name = 'SACHHYA';
My output:
emp_id | age | desegnation | emp_name | exp | mobile
--------+-----+------------------+----------+-----+------------
711 | 22 | Trainee Engineer | SACHHYA | 1 | 9232189345
2 | 24 | Engineer | SACHHYA | 3 | 9033864540
My Table:
emp_id | age | desegnation | emp_name | exp | mobile
--------+-----+------------------+----------+------+------------
5 | 29 | Technical Lead | RAHUL | 9 | 2312343123
10 | 45 | Deleviry Manager | ANDREW | 22 | 9214569345
711 | 22 | Trainee Engineer | SACHHYA | 1 | 9232189345
2 | 24 | Engineer | SACHHYA | 3 | 9033864540
4 | 26 | Engineer | ANKUR | 3 | 3213456321
22 | 20 | Intern | SAM | null | 8858699345
7 | 22 | Trainee Engineer | JACOB | 1 | 9232189345
17 | 28 | Senior Engineer | JACK | 4 | 8890341799
90 | 30 | Senior Engineer | HERCULES | 6 | 9353405163
3 | 32 | Technical Lead | ROSS | 8 | 7876561355

How to Pivot on single column and create multiple columns from it

I have the following table
+---------+----------+--------+------------+------------+
| Country | Provider | Status | End Date | Start Date |
+---------+----------+--------+------------+------------+
| US | P1 | 1 | 1/1/2018 | 2/2/2016 |
| US | P2 | 1 | 11/12/2017 | 3/11/2016 |
| US | P3 | 1 | 10/11/2016 | 4/5/2016 |
| US | P4 | 1 | 5/12/2016 | 9/1/2015 |
| China | P1 | 2 | NA | 2/2/2016 |
| China | P2 | 2 | 11/19/2018 | 3/11/2016 |
| China | P3 | 3 | 6/8/2018 | 4/5/2016 |
| China | P4 | 1 | 9/6/2017 | 9/1/2015 |
+---------+----------+--------+------------+------------+
Expected Result
+---------+------+------+------+------+-----------+-----------+-----------+-----------+---------------+---------------+---------------+---------------+-------------+-------------+-------------+-------------+
| Country | P1 | P2 | P3 | P4 | P1 Status | P2 Status | P3 Status | P4 Status | P1 Start Date | P2 Start Date | P3 Start Date | P4 Start Date | P1 End Date | P2 End Date | P3 End Date | P14End Date |
+---------+------+------+------+------+-----------+-----------+-----------+-----------+---------------+---------------+---------------+---------------+-------------+-------------+-------------+-------------+
| US | NULL | NULL | NULL | NULL | 1 | 1 | 1 | 1 | 2/2/2016 | 3/11/2016 | 4/5/2016 | 9/1/2015 | 1/1/2018 | 11/12/2017 | 10/11/2016 | 5/12/2016 |
| China | NULL | NULL | NULL | NULL | 1 | 2 | 3 | 1 | 2/2/2016 | 3/11/2016 | 4/5/2016 | 9/1/2015 | NA | 11/19/2018 | 6/8/2018 | 9/6/2017 |
+---------+------+------+------+------+-----------+-----------+-----------+-----------+---------------+---------------+---------------+---------------+-------------+-------------+-------------+-------------+
can you guys help me pivot this table to get expected output?
P.S. - Don't worry about the NULL columns (P1, P2, P3 and P4), i can just create them in SELECT statement dynamically.
I have used the MAX function combined with either a CASE or IIF to achieve similar results in the past. Essentially, you have to manually pivot the table. The CASE or IIF is used to only return a value based on the secondary selector (Provider in your case). Then the MAX gets rid of the NULL values created for the other Providers.
Here is an short snippet to get you started. You should be able to expand it out to build up the table you are expecting.
SELECT
Country,
P1Status = MAX(IIF(Provider = 'P1', Status, NULL)),
P2Status = MAX(IIF(Provider = 'P2', Status, NULL)),
P1StartDate = MAX((IIF(Provider = 'P1', StartDate, NULL)),
P2StartDate = MAX((IIF(Provider = 'P1', StartDate, NULL))
FROM
Table
GROUP BY
Country

Resources