Transpose of Query Result - sql

We have a requirement where we need to transpose the query results .The query result is something like below.
Accnt Country Weight
Acct1 US 55
Acct1 GB 45
Acct2 GB 35
Acct2 US 65
The output need to be transposed like below.
Acct1 Acct2
US 55 65
GB 45 35
I have tied declare block ,but this query will be used in Dot net framework where they cant use declare block.So request the experts let me know possible ways to do this in single query ,both initial and the transpose.The accounts will be dynamic .

You can use PIVOT
select *
from (select Accnt,country,weight from test)
pivot (max(weight) for Accnt IN ('Acct1','Acct2'));
COUNTRY 'Acct1' 'Acct2'
US 55 65
GB 45 35

PIVOT is what you need, but there's also another option.
select Country,
max(case when Accnt = 'Acct1' then Weight end) Acct1,
max(case when Accnt = 'Acct2' then Weight end) Acct2
from test
group by Country;

Related

T-SQL Force Select results to have a Primary Key

I have a large set of imperfect data, from this data I reverse engineering a table for the coding used.
For this particular task, it is know that all records with a specific division code should all have the same group ID and plan ID (which are not included in the data) from another source I been able to add a close but imperfect (and incomplete) mapping of the group ID and plan ID. Now I want to work backwards and build a division mapping table. I have gotten data down to a format like this:
Division Year Group Plan Cnt
52 2019 30 101 9031
52 2020 30 101 9562
54 2019 60 602 3510
54 2020 60 602 3385
56 2019 76 904 1113
56 2020 76 905 1125
56 2020 76 001 6
The Division and Year columns should from a primary key. As you can see 56, 2020 is not unique, but by looking at the cnt column it is easy to see that the record with a count of 6 is a bad record and should be dropped.
What I need is a method to return each division and year pair once with the group and plan IDs that have the largest count.
Thank You
I found the answer using the Rank() function and WHERE clause:
SELECT *
FROM (
SELECT Division, Year, Group, Plan_Cd
, RANK() OVER (PARTITION BY Division, Year ORDER BY Cnt DESC ) AS 'rk'
FROM DivisionMap ) R
WHERE rk = 1

Find Maximum across columns in SQL

I have a table with 4 columns SID, Physics, Chemistry, Math. I need to get SID and maximum marks irrespective of the Subject, can anyone help me please.
For Eg
SID Physics Chemistry Maths
1 25 30 85
2 45 28 91
3 97 40 76
Output
SID Max_Marks
3 97
Most databases support least() and greatest(). So, you can do something like this:
select sid, greatest(Physics, Chemistry, Maths) as max_marks
from t
order by max_marks desc
limit 1;
This syntax is more suitable for MySQL. However, you can do something similar in almost any database.

Select rows where value changed in column

Currently I have this table in sql database sorted by Account#.
Account# Charge_code PostingDate Balance
12345 35 1/18/2016 100
**12345 35 1/20/2016 200**
12345 61 1/23/2016 250
12345 61 1/22/2016 300
12222 41 1/20/2016 200
**12222 41 1/21/2016 250**
12222 42 1/23/2016 100
12222 42 1/25/2016 600
How do I select last row prior to the change in the charge_code column for each Account#. I highlighted the rows that I am trying to return.
The query should execute quickly with the table having tens of thousands of records.
In SQL Server 2012+, you would use lead():
select t.*
from (select t.*,
lead(charge_code) over (partition by account order by postingdate) as next_charge_code
from t
) t
where charge_code <> next_charge_code;
In earlier versions of SQL Server, you can do something similar with apply.

Denormalizing using query in Oracle

I've a table like this:
STU_NAME SUBJECT MARKS
--------- --------- ------
1 ENGLISH 90
1 TAMIL 80
1 MATHS 70
2 MATHS 70
2 TAMIL 80
2 ENGLISH 95
And the result should be like below:
STU_NAME MATHS_MARK ENGLISH_MARK TAMIL_MARK TOTAL_MARKS
--------- ----------- ------------ ----------- -------------
1 70 90 80 240
2 70 95 80 245
Can we achieve this with a query?
I find that the easiest way is to use conditional aggregation:
select stu_name,
max(case when subject = 'MATHS' then Marks end) as Maths,
max(case when subject = 'ENGLISH' then Marks end) as English,
max(case when subject = 'TAMIL' then Marks end) as Tamil,
sum(Marks) as Total
from t
group by stu_name;
I got the same using PIVOT function.,
SELECT *
FROM (SELECT *
FROM x)
PIVOT (MAX(marks) FOR (SUBJECT) IN ('ENGLISH', 'MATHS', 'TAMIL'));
But, Still I'm facing few issues.,
whether it is possible to get sum(marks) while using PIVOT.
And getting subjects with respective marks without mentioning every subject(when we do know what are the subjects will be) in both(case,pivot).,?

How to get Result from database by order the condition put in "IN" clause?

Sorry for bad english.
bfproduct is a table and productid is primary key in this table and productname is another field defined in this table.
When i execute this query, select * from bfproduct where productid in (23,5,54,3132,32). The result is as follows:
productid | productname
5 15 Park Avenue
23 Good Boy Bad Boy
32 dsf sf gfdsf dsf d
54 dsdsfsa ffs ff sfsf
3132 Just Books - On The Failure of Legal System
Is there any way i will get the resultset in the order by the productid provided in "IN" Clause e.g.
productid | productname
23 Good Boy Bad Boy
5 15 Park Avenue
54 dsdsfsa ffs ff sfsf
3132 Just Books - On The Failure of Legal System
32 dsf sf gfdsf dsf d
Please help...
Here's one way to do it:
SELECT *
FROM bfproduct
WHERE productid
IN (23,5,54,3132,32)
ORDER BY
CASE productid
WHEN 23 THEN 0
WHEN 5 THEN 1
WHEN 54 THEN 2
WHEN 3132 THEN 3
WHEN 32 THEN 4
END
First thing I can think of, try something like...
select bfproduct.*
from bfproduct INNER JOIN
(
select 1 as sequence, 23 as productid
union
select 2,5
union
select 3,54
union
select 4,3132
union
select 5,32
) as lookup on bfproduct.productid=lookup.productid
order by lookup.sequence
(I haven't tested this so there maybe some minor syntax errors!)
You have to add a ORDER BY clause that puts the rows to correct order.