Table data into Pivot - sql-server

An Accounting Table has the sample data shown below:
(There could be more AcctgHeads than those shown here)
+-------+-----------+--------+-----+
| Loan | AcctgHead | Amount | D_C |
+-------+-----------+--------+-----+
| 1 | Principal | 10000 | D |
| 1 | Principal | 500 | C |
| 1 | Cash | 10000 | C |
| 1 | Cash | 500 | D |
| 2 | Principal | 5000 | D |
| 2 | Cash | 5000 | C |
| 2 | Cash | 300 | D |
| 2 | Principal | 300 | C |
| 1 | IntDue | 50 | D |
| 1 | IntIncome | 50 | C |
+-------+-----------+--------+-----+
The desired ouput is:
+------+-------------+-------------+--------+--------+----------+----------+-------------+-------------+
| Loan | Principal_D | Principal_C | Cash_D | Cash_C | IntDue_D | IntDue_C | IntIncome_D | IntIncome_C |
+------+-------------+-------------+--------+--------+----------+----------+-------------+-------------+
| 1 | 10000 | 500 | 500 | 10000 | 50 | 0 | 0 | 50 |
| 2 | 5000 | 300 | 300 | 5000 | 0 | 0 | 0 | 0 |
+------+-------------+-------------+--------+--------+----------+----------+-------------+-------------+
What would be the query to accomplish this?
Thanks in advance for the help.

Try this: (assuming your acctghead has fixed number of values as shown)
select loan,
isnull(Principal_D,0) Principal_D,
isnull(Principal_C,0) Principal_C,
isnull(Cash_D,0) Cash_D,
isnull(Cash_C,0) Cash_C,
isnull(IntDue_D,0) IntDue_D,
isnull(IntDue_C,0) IntDue_C,
isnull(IntIncome_D,0) IntIncome_D,
isnull(IntIncome_C,0) IntIncome_C
from
(select loan, amount, AcctgHead + '_' + D_C As AcctgHeadDC from t) t
pivot
(
max(amount) for AcctgHeadDC in
(Principal_D,Principal_C,Cash_D,Cash_C,
IntDue_D,IntDue_C,IntIncome_D,IntIncome_C)
) p
SQL DEMO

Related

Sum, Group by and Null

I'm dipping my toes into SQL. I have the following table
+------+----+------+------+-------+
| Type | ID | QTY | Rate | Name |
+------+----+------+------+-------+
| B | 1 | 1000 | 21 | Jack |
| B | 2 | 2000 | 12 | Kevin |
| B | 1 | 3000 | 24 | Jack |
| B | 1 | 1000 | 23 | Jack |
| B | 3 | 200 | 13 | Mary |
| B | 2 | 3000 | 12 | Kevin |
| B | 4 | 4000 | 44 | Chris |
| B | 4 | 5000 | 43 | Chris |
| B | 3 | 1000 | 26 | Mary |
+------+----+------+------+-------+
I don't know how I would leverage Sum and Group by to achieve the following result.
+------+----+------+------+-------+------------+
| Type | ID | QTY | Rate | Name | Sum of QTY |
+------+----+------+------+-------+------------+
| B | 1 | 1000 | 21 | Jack | 5000 |
| B | 1 | 3000 | 24 | Jack | Null |
| B | 1 | 1000 | 23 | Jack | Null |
| B | 2 | 3000 | 12 | Kevin | 5000 |
| B | 2 | 3000 | 12 | Kevin | Null |
| B | 3 | 200 | 13 | Mary | 1200 |
| B | 3 | 1000 | 26 | Mary | Null |
| B | 4 | 4000 | 44 | Chris | 9000 |
| B | 4 | 5000 | 43 | Chris | Null |
+------+----+------+------+-------+------------+
Any help is appreciated!
You can use window function :
select t.*,
(case when row_number() over (partition by type, id order by name) = 1
then sum(qty) over (partition by type, id order by name)
end) as Sum_of_QTY
from table t;

Need to update "orderby" column

I have a table test
+----+--+------+--+--+----------+--+--------------+
| ID | | Name | | | orderby | | processgroup |
+----+--+------+--+--+----------+--+--------------+
| 1 | | ABC | | | 10 | | 1 |
| 10 | | DEF | | | 12 | | 1 |
| 15 | | LMN | | | 1 | | 1 |
| 44 | | JKL | | | 4 | | 1 |
| 42 | | XYZ | | | 3 | | 2 |
+----+--+------+--+--+----------+--+--------------+
I want to update the orderby column in the sequence, I am expecting output like
+----+--+------+--+--+----------+--+--------------+
| ID | | Name | | | orderby | | processgroup |
+----+--+------+--+--+----------+--+--------------+
| 1 | | ABC | | | 1 | | 1 |
| 10 | | DEF | | | 2 | | 1 |
| 15 | | LMN | | | 3 | | 1 |
| 44 | | JKL | | | 4 | | 1 |
| 42 | | XYZ | | | 5 | | 1 |
+----+--+------+--+--+----------+--+--------------+
Logic behind this is when we have procesgroup as 1, orderby column should update as 1,2,3,4 and when procesgroup is 2 then update orderby as 5.
This might help you
;WITH CTE AS (
SELECT ROW_NUMBER() OVER (ORDER BY processgroup, ID ) AS SNO, ID FROM TABLE1
)
UPDATE TABLE1 SET TABLE1.orderby= CTE.SNO FROM CTE WHERE TABLE1.ID = CTE.ID

Row number by 3 distincts fields in SQL Server

I have this table:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 |
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 |
I want add a new column row number based on JourneyNumber, SegmentNumber and LegNumber, order by RecordLocator, for obtain this result:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber | rowNum |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|--------|
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 | 1 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 | 2 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 | 3 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 | 4 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 | 5 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 | 6 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 | 7 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 | 8 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 | 1 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 | 2 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 | 3 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 | 4 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 | 5 |
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 | 6 |
I tried this query:
SELECT
RecordLocator,
DepartureStation, ArrivalStation,
JourneyNumber, SegmentNumber,
LegNumber, FlightNumber,
(SELECT ((P.JourneyNumber + P.SegmentNumber + P.LegNumber))
FROM PAX P2
WHERE P2.RecordLocator = P.RecordLocator
AND P2.DepartureStation = P.DepartureStation
AND P2.ArrivalStation = P.ArrivalStation
AND P2.JourneyNumber = P.JourneyNumber
AND P2.SegmentNumber = P.SegmentNumber
AND P2.LegNumber = P.LegNumber
AND P2.FlightNumber = P.FlightNumber) AS rowNum
FROM
PAX P
I'm trying sum the columns JourneyNumber, SegmentNumber and LegNumber but does not work, i belive best way to do, is based on Recordlocator define a "weight" for the columns JourneyNumber > SegmentNumber > LegNumber, but i don't know how implement it.
In C# I know how to do it, using align for:
// First `for` - Journey
for(int i = 0; i < Journey.Count(); i++)
{
// Second `for` - Segment
for(int j = 0; j < Segment.Count(); j++)
{
// Third `for` - Leg
for(int k = 0; k < Leg.Count(); k++)
{
result = i + j + k;
}
}
}
Basically, breaking down your question into its parts, you want to re-start numbering for each RecordLocator, then you order it by the 3 fields you wanted in ascending order.
Overall, that's the idea of the ROW_NUMBER() which allows for ordering your records with a partition set for RecordLocator to re-start the numbering as needed. So, something like this should do it:
ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber)
And your final SQL, therefore, becoming:
SELECT RecordLocator
, DepartureStation
, ArrivalStation
, JourneyNumber
, SegmentNumber
, LegNumber
, FlightNumber
, ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber) AS rowNum
FROM PAX P
Hope this does the trick!

SSRS 2008 R2 Row/Column Group Issues

I am using Row Group And Column Group in SSRS 2008 R2.
I have design the report contain two row groups(et.Pixel、Name) and one column group(et.Date).
Preview Report as bellow:
| Date1 | Date2 | Date2 |
Pixel | Name | Input | Ng | Name | Input | Ng | Name | Input | Ng |
| XXX1 | 1000 | 2 | | | | | | |
| | | | YYY1 | 2000 | 1 | | | |
2M | | | | YYY2 | 1000 | 2 | | | |
| | | | YYY3 | 3000 | 5 | | | |
| | | | | | | ZZZ1 | 800 | 2 |
| | | | | | | ZZZ2 | 500 | 3 |
|Total | 1000 | 2 |Total | 6000 | 8 |Total | 1300 | 5 |
My question is, How do I get the Preview Report don't show white space column in report.
For example:
| Date1 | Date2 | Date2 |
Pixel | Name | Input | Ng | Name | Input | Ng | Name | Input | Ng |
| XXX1 | 1000 | 2 | YYY1 | 2000 | 1 | ZZZ1 | 800 | 2 |
2M | | | | YYY2 | 1000 | 2 | ZZZ2 | 500 | 3 |
| | | | YYY3 | 3000 | 5 | | | |
|Total | 1000 | 2 |Total | 6000 | 8 |Total | 1300 | 5 |
It's the grouping by name which is causing the issue that you are having. Since the name is different they won't be on the same line.
On the plus side, you can probably work around this. If the data is like you display it, I would group on the numeric number in the name instead of the whole name.
=MID(Fields!Name.Value, 4, LEN(Fields!Name.Value) - 3)
Of course you couldn't have XXX and YYY data on the same date with this expression otherwise you would have multiple rows.

Multifilter SQL Server Pivot Count Query to table

I have never used SQL Pivot before and need help
I have the following data table (wkYield) in MS SQL Server 2012 which looks like:
| id | Trav_num | Part_num | Reason_code | Scrap | date |
| 1 | 123123 | 400 | cw_iweld | 1 | 1/1/2015 |
| 2 | 123122 | 400 | cw_iweld | 1 | 1/1/2015 |
| 3 | 123124 | 400 | cw_iweld | 0 | 1/7/2015 |
| 4 | 123124 | 400 | cw_iweld | 1 | 1/7/2015 |
| 5 | 123121 | 400 | cw_hole | 0 | 1/1/2015 |
| 6 | 123121 | 400 | cw_hole | 1 | 1/1/2015 |
| 7 | 123110 | 400 | cw_hole | 0 | 1/7/2015 |
| 8 | 123110 | 400 | cw_hole | 1 | 1/7/2015 |
| 9 | 123111 | 410 | cw_iweld | 0 | 1/1/2015 |
| 10 | 123111 | 410 | cw_iweld | 1 | 1/1/2015 |
| 11 | 123333 | 410 | cw_iweld | 1 | 1/1/2015 |
I would like to use SQL to pivot the data to count the # of rows and display like the following:
| Part_num | Reason_code | Week | Scrap=1 Cnt(reason)| Scrap=0 Cnt(reason)|
| 400 | cw_weld | 1 | 2 | 1 |
| 400 | cw_hole | 1 | 1 | 1 |
| 400 | cw_weld | 2 | 1 | 1 |
| 400 | cw_hole | 2 | 1 | 1 |
| 410 | cw_iweld | 1 | 2 | 1 |
And then the result should be placed in table wkYieldSum
I don't know for any given week number what the reason codes are (They change week to week but do have a lot of repeats.
All your help is very appreciated!
You can do this two ways one is conditional Aggregate another way is Pivot. I prefer Conditional Aggregate which more readable in my opinion
select Part_num,
Reason_code,
datepart(Week,[date]) as [Week],
count(case when Scrap=1 then 1 end) as [Scrap=1 Cnt(reason)],
count(case when Scrap=0 then 1 end) as [Scrap=0 Cnt(reason)],
From Yourtable
Group by Part_num,
Reason_code,
datepart(Week,[date])

Resources