How to pivot data in SQL - sql

I have data that looks much like this (3 columns of data), unfortunately I can't get it to display properly
NCR NO LU_NAME KEY_REF
100001 Project PROJECT_ID=ID#^
100001 SupplierInfo SUPPLIER_ID=UNIQUESUPPLIERNUMBER^
100001 PurchaseOrder ORDER_NO=UNIQUEORDERNO^
100196 PurchaseReceipt UNIQUE PURCHASE RECEIPT
100511 InventoryPart CONTRACT=UNIQUECONTRACTNO
What I want is to have one record for each NCR number and a column of data for Project, SupplierInfo, etc, which contains the unique Key_Ref. Let's say the table name is OC. Can someone assist with the code to do this?

This type of data transformation is called a pivot, some database products have a function that can do this for you.
If you are working in a database that does not have a pivot function, then you can use an aggregate function with a CASE expression:
select ncr_no,
max(case when LU_NAME = 'Project' then KEY_REF end) Project,
max(case when LU_NAME = 'SupplierInfo' then KEY_REF end) SupplierInfo,
max(case when LU_NAME = 'PurchaseOrder' then KEY_REF end) PurchaseOrder,
max(case when LU_NAME = 'PurchaseReceipt' then KEY_REF end) PurchaseReceipt,
max(case when LU_NAME = 'InventoryPart' then KEY_REF end) InventoryPart
from yourtable
group by ncr_no
See SQL Fiddle with Demo.
The above will work great with a known number or finite number of LU_NAME values, if you will have an unknown number then you will need to implement dynamic SQL but that code will vary depending on your database.

Related

Dynamic Pivot of multi-columns based on rank of row Oracle and SQL Server

I have data as below :
and I'm trying to get it into this shape:
I've seen this solution Multi Column Pivot SQL Server but it uses hardcoding values, which is not my case, hence I think it would be safer to use dynamic pivot.
Can anyone help?
You can use conditional aggregation:
select id_card_no,
max(case when city_rank = 1 then city end) as city_1,
max(case when city_rank = 1 then visitratio end) as visitratio_1,
max(case when city_rank = 2 then city end) as city_2,
max(case when city_rank = 2 then visitratio end) as visitratio_2
from t
group by id_card_no;
This is standard SQL and should work in any database.

how to consolidate information from various rows in to 1 in SQL Server?

I have a table in SQL Server called [orders]:
I have another table called [order_details]:
as you can see, if the media_type is various in [orders] table, there will be 2 corresponding rows in [order_details].
how can i make the below table?
i was trying the method that the admins suggested even before they closed down my original question but what i was getting was the below:
i need this to be like:
You seem to just want conditional aggregation on order_details:
select od.order_id,
sum(case when od.media_type = 'Loose Cartons' then qty else 0 end) as loose_cartons,
sum(case when od.media_type = 'Loose Units' then qty else 0 end) as loose_units
from order_details od
group by od.order_id;
you would just perform an aggregation on the query that got you these results
select [order id]
,max(pallets) as pallets
,max([total cartons]) as [total cartons]
,max(units) as units
,max(sets) as sets
,max(GOH) as GOH
,max([Loose Cartons]) as [Loose Cartons]
,max([Loose Units]) as [Loose Units]
from (<insert query that got you the results with two records >
)
group by [order id]
ok guys sorted.
So i had to create a separate table with just the order_id and 3 more columns with Pallets, Cartons and Sets.
i had to use "max" not "sum" otherwise it would double the quantity.
so what i used was:
create view SSDView_2ND_VB as
select
a.ORDER_ID
,max(case when b.MEDIATYPE_ID = '1' then b.ORDER_DETAIL_QUANTITY else null end) as [Pallets]
,max(case when b.MEDIATYPE_ID = '2' then b.ORDER_DETAIL_QUANTITY else null end) as [Cartons]
,max(case when b.MEDIATYPE_ID = '3' then b.ORDER_DETAIL_QUANTITY else null end) as [Sets]
from
SSDView_1ST_VB as a
left join ORDER_DETAIL as b
on a.ORDER_ID = b.ORDER_ID
group by a.ORDER_ID
The SSDView_1ST_VB was just another view which only had media type 'VARIOUS'.
I would like to thank you all for your help, really appreciate it guys ^^

Pivot rows into unknown number of columns

I have an access to Oracle server. There is a table on the Oracle server called Transactions which contains the following data:
I don't known the number of values, so we need to implement dynamic sql in Oracle.
I need to pivot that data so the results are:
Any suggestions?
You can use conditional aggregation:
select subno,
sum(case when offer = 'offer1' then 1 else 0 end) as offer1,
sum(case when offer = 'offer2' then 1 else 0 end) as offer2,
sum(case when offer = 'offer3' then 1 else 0 end) as offer3
from t
group by subno;

Index - Match like function in PL-SQL

Recently I have very specific problem with data we get from our data-warehouse. The problem is being solved, but I have to edit our control environment for a while.
We have data about received invoices, however due to some reason, information about every invoice is split into two rows: First row has important columns unique_code_A, vendor_number, and the second row has important columns unique_code_B, amount. So every invoice has very specific unique code, and with this code I have to somehow join the information from both rows, as you can see in picture.
Well, you can use aggregation:
select date_key, invoice_type,
max(case when unique_code_b is null then unique_code_a end) as unique_code_a,
max(unique_code_b) as unique_code_b,
max(case when unique_code_b is null then vendor_number end) as vendor_number,
max(case when unique_code_b is not null then amount end) as amount
from t
group by date_key, invoice_type;
EDIT:
If the unique codes can be used for matching, then I would suggest:
select date_key, invoice_type,
coalesce(unique_code_a, unique_code_b) as unique_code,
max(case when unique_code_b is null then vendor_number end) as vendor_number,
max(case when unique_code_b is not null then amount end) as amount
from t
group by date_key, invoice_type, coalesce(unique_code_a, unique_code_b);
From what you told, a self join should probably work:
SELECT
A.DATE_KEY,
A.INVOICE_TYPE,
A.UNIQUE_CODE_A,
B.UNIQUE_CODE_B,
A.VENDOR_NUMBER,
B.AMOUNT
FROM MyTable A
INNER JOIN MyTable B ON A.UNIQUE_CODE_A=B.UNIQUE_CODE_B

SQL transpose multi column table without aggregation

I have a dataset in the format;
And need to it in the format;
I have had various attempts at pivot and unpivot for the last week but am not a real programmer and know when to ask a grownup for help.
The database is running on MSSQL 2012 and the dataset will consist of 14 Mode_Antibiotics, ModeQualifier and ModeMIC entries per ClinicalTrialID with a total of approximately 3000 ClinicalTrialIDs.
It's going to be hard to do it in pure SQL dynamically. If I new T-SQL, I would write a table function returning the required dataset. However, in a pure ANSI SQL, since you don't have that many columns, you could use something like this:
SELECT
ClinicalTrialID,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_Antibiotic
END) Antibiotic1,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_Qualifier
END) Qualifier1,
MAX(CASE
WHEN Mode_Antibiotic = 'Amikacin'
THEN Mode_MIC
END) MIC1,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_Antibiotic
END) Antibiotic2,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_Qualifier
END) Qualifier2,
MAX(CASE
WHEN Mode_Antibiotic = 'Ampicillin'
THEN Mode_MIC
END) MIC2,
-- repeat 12 times with the remaining antibiotics
FROM t
GROUP BY ClinicalTrialID;
Hope that helps.