Sql Grouping Query - sql

I'm wondering how i can get a query to put these groupings into one line so i can put it into a vb.net datagrid.
For example Number, Company Name, Current, 31-60, 61-90
Which would be for example company A, but get the grouping to all be on one line.
104680777, Company A, 643546.344, 34534534.77, 3454.55
To even get this query below. I had to do this.
select sum(Amount), DunsNum, CompanyName, Age
from tblARAged
group by DunsNum, Age, CompanyName
Amount Num CompanyName Age
63546.344 104680777 Company a 1
34534534.77 104680777 Company a 2
3454.55 104680777 Company a 3
3453453.66 186830733 Company b 1
345342.45 186830733 Company b 2
4542.55 186830733 Company c 3
3434.55 26409797 Company c 1
345345 26409797 Company c 2
The 1 correlates to current, 2 correlates to 31-60 and 3 correlates to 61-90 for age

I would do what Nimesh stated, though I would make a few tweaks. You want to do aggregation as late as possible:
SELECT DunsNum ,
CompanyName ,
SUM(CASE WHEN ( Age = 1 ) THEN Amt
ELSE 0
END) AS [Amount_Cur] ,
SUM(CASE WHEN ( Age = 2 ) THEN Amt
ELSE 0
END) AS [Amount_31-60] ,
SUM(CASE WHEN ( Age = 3 ) THEN Amt
ELSE 0
END) AS [Amount_61-90]
FROM tblARAged
GROUP BY DunsNum ,
CompanyName;
I haven't tested this code

Related

Pivot without aggregation in SQL

I am trying to figure out how to pivot column to row without aggregation.
I have a table with Account, Company Name and Company %. I am trying to pivot so that all companies info with respect to that account are on the same row. There isn't a limit on how many companies an account could have and I will need to include all companies.
Currently:
Account
Company Name
Company %
1
Company A
Company A%
1
Company B
Company B%
2
Company B
Company B%
3
Company A
Company A%
3
Company B
Company B%
3
Company K
Company K%
3
Company W
Company W%
Expected Results:
Account
Company 1
Company 1%
Company 2
Company 2%
Company 3
Company 3%
Company 4
Company 4%
1
Company A
Company A%
Company B
Company B%
2
Company B
Company B%
3
Company A
Company A%
Company B
Company B%
Company K
Company K%
Company W
Company W%
Any modern implementation of SQL has ROW_NUMBER() and that can be used for what you want.
It still uses MAX() to collapse multiple rows in to single rows, but it is being used as pick the one value that isn't NULL.
There is no sane reason to avoid its use.
WITH
sorted AS
(
SELECT
yourTable.*,
ROW_NUMBER() OVER (PARTITION BY account ORDER BY company_name) AS account_row_id
FROM
yourTable
)
SELECT
account,
MAX(CASE WHEN account_row_id = 1 THEN company_name END) AS company_name_1,
MAX(CASE WHEN account_row_id = 1 THEN company_pct END) AS company_pct_1,
MAX(CASE WHEN account_row_id = 2 THEN company_name END) AS company_name_2,
MAX(CASE WHEN account_row_id = 2 THEN company_pct END) AS company_pct_2,
MAX(CASE WHEN account_row_id = 3 THEN company_name END) AS company_name_3,
MAX(CASE WHEN account_row_id = 3 THEN company_pct END) AS company_pct_3,
MAX(CASE WHEN account_row_id = 4 THEN company_name END) AS company_name_4,
MAX(CASE WHEN account_row_id = 4 THEN company_pct END) AS company_pct_4
FROM
sorted
GROUP BY
account
ORDER BY
account

Group rows while excluding null values on specific column and aggregating another

I have a table like this
CUSTOMER_ID
ALIAS_ID
ULTIMATE_NAME
MODEL_SUB_TYPE
OLD_PD
OLD_EXP
OLD_ECAP
RATING
Client A
123
Company A
CI_COM_KN
1
1
1
BB+
Client A
123
Company A
CI_POL_KN
0.5
1
1
null
Client A
456
Company B
CI_COM_KN
1
1
3
BB+
Client A
456
Company B
CI_POL_KN
0.5
1
3
null
What I need my query to do is to ignore the values in OLD_PD, OLD_EXP and RATING columns when MODEL_SUB_TYPE = Sub_type B, and aggregate (sum) the OLD_ECAP column regardless of MODEL_SUB_TYPE.
What I have so far is this:
SELECT
CUSTOMER_ID,
ALIAS_ID,
SUBSTR(ULTIMATE_NAME, 0, 70) as ULTIMATE_NAME,
MODEL_SUB_TYPE,
CASE
WHEN MODEL_SUB_TYPE LIKE 'CI_COM_%' THEN ULTIMATE_POD
END AS OLD_PD,
SUM(
CASE
WHEN MODEL_SUB_TYPE LIKE 'CI_COM_%' THEN CREDIT_LIMIT_NET_EXPOSURE
END
) AS OLD_EXP,
SUM(EC_CONSUMPTION_ND) AS OLD_ECAP,
ULTIMATE_RATING AS RATING
FROM
CALC6619.SO_REPORTING -- OLD QUARTER --
WHERE
MODEL_TYPE LIKE 'IR'
AND MODEL_SUB_TYPE LIKE 'CI_%'
AND CUSTOMER_ID = '09781C1 01' -- Customer ID
GROUP BY
CUSTOMER_ID,
ALIAS_ID,
ULTIMATE_NAME,
MODEL_SUB_TYPE,
ULTIMATE_POD,
ULTIMATE_RATING
What I want is my query to return a table like this (based on table above):
CUSTOMER_ID
ALIAS_ID
ULTIMATE_NAME
MODEL_SUB_TYPE
OLD_PD
OLD_EXP
OLD_ECAP
RATING
Client A
123
Company A
CI_COM_KN
1
1
2
BB+
Client A
456
Company B
CI_COM_KN
1
1
6
BB+
But it's actually returning a table like the first one, but with null values where it's supposed to be, but not grouping the rows per company ID, like so:
CUSTOMER_ID
ALIAS_ID
ULTIMATE_NAME
MODEL_SUB_TYPE
OLD_PD
OLD_EXP
OLD_ECAP
RATING
Client A
123
Company A
CI_COM_KN
1
1
1
BB+
Client A
123
Company A
CI_POL_KN
null
null
1
null
Client A
456
Company B
CI_COM_KN
1
1
3
BB+
Client A
456
Company B
CI_POL_KN
null
null
3
null
You just have to remove the columns from group by and do some changes in SELECT clause as follows:
SELECT
CUSTOMER_ID,
ALIAS_ID,
SUBSTR(ULTIMATE_NAME, 0, 70) as ULTIMATE_NAME,
MAX(CASE WHEN MODEL_SUB_TYPE LIKE 'CI_COM_%' THEN MODEL_SUB_TYPE END) AS MODEL_SUB_TYPE,
SUM(CASE
WHEN MODEL_SUB_TYPE LIKE 'CI_COM_%' THEN ULTIMATE_POD
END) AS OLD_PD,
SUM(
CASE
WHEN MODEL_SUB_TYPE LIKE 'CI_COM_%' THEN CREDIT_LIMIT_NET_EXPOSURE
END
) AS OLD_EXP,
SUM(EC_CONSUMPTION_ND) AS OLD_ECAP,
MAX(ULTIMATE_RATING) AS RATING
FROM
CALC6619.SO_REPORTING -- OLD QUARTER --
WHERE
MODEL_TYPE LIKE 'IR'
AND MODEL_SUB_TYPE LIKE 'CI_%'
AND CUSTOMER_ID = '09781C1 01' -- Customer ID
GROUP BY
CUSTOMER_ID,
ALIAS_ID,
SUBSTR(ULTIMATE_NAME, 0, 70)

Creating separate columns based on the main column in a sql table.?

I have a table with thousands of record which has a structure like below :
Street
House
Persons
1
A
2
1
B
5
1
C
3
2
D
6
2
E
9
3
F
4
I want to frame a sql query such that its output will be like:
Street
House
Persons
House
Persons
House
Persons
1
A
2
B
5
C
3
2
D
6
E
9
null
null
3
F
4
null
null
null
null
The number of house in a street is not the same for all the streets and it varies based on the street.
Can someone please help me in framing this query? Thanks!
For a fixed maximum number of rows per street, you can use window functions and aggregation:
select street,
max(case when rn = 1 then house end) as house1,
max(case when rn = 1 then persons end) as persons1,
max(case when rn = 2 then house end) as house2,
max(case when rn = 2 then persons end) as persons2
from (
select t.*,
row_number() over(partition by street order by house) rn
from mytable t
) t
group by street
You can add more conditional expressions to the select clause to handle more rows per street.

Sort by aggregate value in sql

Let's say I have the following student data:
classroom gender student_id
-------------------------------------
First Grade M 123
First Grade F 124
First Grade F 125
Second Grade M 126
Third Grade M 127
...
I want to produce the following result: top 3 biggest classrooms ordered by total number of students with detail for each:
classroom boys_count girls_count total_count
--------------------------------------------------
Third Grade 30 30 60
First Grade 20 5 25
Fourth Grade 10 10 20
How can I do that in sql ? If necessary, I can use specific postrges features.
What I tried so far:
SELECT count(*) as total_count
, gender
, classroom
ORDER BY 1
GROUP BY classroom, gender
LIMIT 3
Then I re-organise results in some scripting language. But this is too slow. I want to have the correct results with one query
select classroom as name,
sum(case when gender = 'M' then 1 else 0 end) as boys_count,
sum(case when gender = 'F' then 1 else 0 end) as girls_count,
count(*) as total_count
from your_table
group by classroom
order by count(*) desc
limit 3

Count without nested select: is this possible?

Database:
Department Position Points
A Manager 50
A Supervisor 10
A Supervisor 10
A Staff 2
A Staff 2
B Manager 40
B SuperVisor 8
B Staff 2
B Staff 2
B Staff 2
Desired query result:
Dept Manager Count Supervisor Count Staff Count Staff Total Pts
A 1 2 2 4
B 1 1 3 4
Is the desired query result possible without using nested select with count?
We have a certain stored procedure similar to this using nested counts and we like to make it simpler and perform better/faster
Use Conditional Aggregate to count only the specific data
Select Department,
count(case when Position = 'Manager' then 1 END) as Manager,
count(case when Position = 'Supervisor' then 1 END) as Supervisor,
count(case when Position = 'Staff' then 1 END) as Staff
From yourtable
Group by Department
If you are using Sql Server use this
SELECT Department,
Manager,
Supervisor,
Staff
FROM Yourtable
PIVOT (Count(Position)
FOR Position IN (Manager,Supervisor,Staff))pv
Use conditional SUM:
SELECT Department,
SUM(CASE WHEN Position = 'Manager' THEN 1 END) as Manager,
SUM(CASE WHEN Position = 'Supervisor' THEN 1 END) as Supervisor,
SUM(CASE WHEN Position = 'Staff' THEN 1 END) as Staff
FROM yourtable
GROUP BY Department
Or You can use PIVOT operator:
select Detartment, Manager, Supervisor, Staff
from yourtable
pivot (count(Position) for Position in (Manager, Supervisor, Staff)) Result