How to pivot a single row summary in postgresql - sql

SQLFiddle here: http://sqlfiddle.com/#!15/e8e49/2/0
I want to get some summary data from my table into rows instead of columns..
select
sum(n),
avg(n),
max(n),
min(n)
from Table1
this returns a single row, multi-column result.
How can I get it into a result that's something like this:
Label | Res
-------------
min | 2
max | 3
count | 30
... etc ...

Postgres does not have a pivot trasformation...
select
'sum' as "key",sum(n) as "value" from Table1
union all
select 'avg', avg(n) from Table1
union all
select 'max', max(n) from Table1
union all
select 'min', min(n) from Table1
or if you have superuser can try CREATE EXTENSION tablefunc

Related

SQL : How to find the count of an particular category values from an column with string values

I have a SQL Table called "category" looks like this
id | category
--------------
1 | 3,2
2 | 1
3 | 4,3,2
4 | 2,1
5 | 1,4
6 | 2,3,4
There are multiple category id's in the column "category", I need to find the count of an particular category values.
Current method I am using is:
select count(distinct(Category)) AS coldatacount from table_name
It gives the count of all the distinct values WHERE as I need to get
the count of all the particular category_id's separately.
if you are trying to get the Category Ids in comma delimited, you can use the string_split function to get distinct category_id
with cte as (
select 1 as id, '3,2' as category union all
select 2, '1' union all
select 3, '4,3,2' union all
select 4, '2,1' union all
select 5, '1,4' union all
select 6, '2,3,4'
)select count(distinct(value)) as category from cte
cross apply string_split(cte.category, ',');
I assumed that #neeraj04 may be looking for count of all Id in the category, continuing with #METAL code:
CREATE TABLE YourTable
(
Id INT IDENTITY,
[Category] VARCHAR(50)
);
INSERT YourTable VALUES ('3,2'), ('1'), ('4,3,2'), ('2,1'), ('1,4'), ('2,3,4');
SELECT CAST(value AS INT) AS category -- Value is string ouptut
, COUNT([value]) AS IdCount
FROM YourTable yt
CROSS APPLY string_split(yt.Category, ',')
GROUP BY [value]
ORDER BY category;
This is a horrible data model. You should not be storing multiple values in a string. You should not be storing numbers as strings.
Sometimes we are stuck with other people's really, really bad decisions. One approach is to split the string and count:
select t.*, cnt
from t cross apply
(select count(*) as cnt
from string_split(t.category) s
) s;
The other is to count commas:
select t.*,
(1 + len(t.category) - len(replace(t.category, ',', '')) as num_elements
Select Count(Value) from (Select Value from Table_Name a Cross Apply
string_split(a.Category, ','))ab Where Value=1

Dynamic Pivoting in Oracle

Hi I want to apply dynamic pivoting on table with structure as
ID Type Amount
--- ------ ------
1 AB 50
2 PQR 100
3 AB 60
4 PQR 120
I want result in below format:
In my table, every month Type column's values changing. So I want dynamically pivot table values to get desired result. I was tried by pivoting as per syntax , but whenever I tried to place sub-query in IN operator of pivot, it has given an error. I am using Oracle 10 g.
Can anyone please assist me in this issue. Thanks.
Select * from(
Select ID , Type, Value
from mytable)x
pivot(sum(Value) for Type IN (Select distinct Type from myTable))
If you want to have dynamic results, you may prefer using xml option of pivoting
with t(ID, Type, Amount) as
(
select 1,'AB',50 from dual union all
select 2,'PQR',100 from dual union all
select 3,'AB',60 from dual union all
select 4,'PQR',120 from dual
)
select *
from(
select ID , Type, Amount
from t )
pivot xml(
sum(Amount) as sum_amount for (type)
in (Select distinct Type from t)
);
Rextester Demo

sql - getting sum of same column from multiple tables

I have a few tables in my DB. Let's call them table1, table2, table3.
All of them have a column named value.
I need to create a query that will return a single number, where this number is the sum of all the value columns from all the tables together...
I've tried the following way:
SELECT (SELECT SUM(value) FROM table1) + (SELECT SUM(value) FROM table2) + (SELECT SUM(value) FROM table3) as total_sum
But when at least one of the inner SUM is NULL, the entire total value (total_sum here) is NULL, so that's not very trustworthy.
When there is no value in a certain inner SUM query, I need it to return 0, so it doesn't affect the rest of the SUM.
To make it more clear, let's say I have the following 2 tables:
TABLE1:
ID | NAME | VALUE
1 Name1 1000
2 Name2 2000
3 Name3 3000
TABLE2:
ID | NAME | VALUE
1 Name1 1500
2 Name2 2500
3 Name3 3500
Eventually, the query I need will return a single value - 13500, which is the total sum of all the values under the VALUE column of all the tables here.
All the other columns have no meaning for the needed query, and I even don't care much for performance in this case.
You can achieve it using Coalesce as follows
SELECT
(SELECT coalesce(SUM(value),0) FROM table1) +
(SELECT coalesce(SUM(value),0) FROM table2) +
(SELECT coalesce(SUM(value),0) FROM table3) as total_sum
Another approach is to use union all to merge all values into single table
select distinct coalesce(sum(a.value), 0) as total_sum from
(select value from table1
union all
select value from table 2
union all
select value from table 3) a;
You can use the ISNULL function to take care of the NULLs.
SELECT ISNULL((
SELECT SUM(value) FROM table1
)
, 0
) + ISNULL((
SELECT SUM(value) FROM table2
)
, 0
) + ISNULL((
SELECT SUM(value) FROM table3
)
, 0
) AS total_sum;
You could simply sum all of them:
select sum(total) as Total
from (
select sum(value) as total from Table1
union all
select sum(value) as total from Table2
union all
select sum(value) as total from Table3
) t;

Counting the rows of a column where the value of a different column is 1

I am using a select count distinct to count the number of records in a column. However, I only want to count the records where the value of a different column is 1.
So my table looks a bit like this:
Name------Type
abc---------1
def----------2
ghi----------2
jkl-----------1
mno--------1
and I want the query only to count abc, jkl and mno and thus return '3'.
I wasn't able to do this with the CASE function, because this only seems to work with conditions in the same column.
EDIT: Sorry, I should have added, I want to make a query that counts both types.
So the result should look more like:
1---3
2---2
SELECT COUNT(*)
FROM dbo.[table name]
WHERE [type] = 1;
If you want to return the counts by type:
SELECT [type], COUNT(*)
FROM dbo.[table name]
GROUP BY [type]
ORDER BY [type];
You should avoid using keywords like type as column names - you can avoid a lot of square brackets if you use a more specific, non-reserved word.
I think you'll want (assuming that you wouldn't want to count ('abc',1) twice if it is in your table twice):
select count(distinct name)
from mytable
where type = 1
EDIT: for getting all types
select type, count(distinct name)
from mytable
group by type
order by type
select count(1) from tbl where type = 1
;WITH MyTable (Name, [Type]) AS
(
SELECT 'abc', 1
UNION
SELECT 'def', 2
UNION
SELECT 'ghi', 2
UNION
SELECT 'jkl', 1
UNION
SELECT 'mno', 1
)
SELECT COUNT( DISTINCT Name)
FROM MyTable
WHERE [Type] = 1

Get the number of columns in two SQL tables in a single query?

I've written two SQL statements:
SELECT Count(*) AS table1Count FROM table1 WHERE foo=1;
SELECT Count(*) AS table2Count FROM table2 WHERE bar=2;
Both statements return the data I want, but I would like to know how to return a single table with two cells: table1Count and table2Count from a single query.
How do I do construct the query?
SELECT (SELECT Count(*) AS table1Count FROM table1 WHERE foo=1) AS table1Count,
(SELECT Count(*) AS table2Count FROM table2 WHERE bar=2) AS table2Count;
Gives something like:
table1count | table2count
-------------+-------------
4 | 6
(1 row)
With UNION ALL:
SELECT 'Table1' AS "Table", Count(*) As "Count" FROM table1 WHERE foo=1
UNION ALL
SELECT 'Table2' AS "Table", Count(*) As "Count" FROM table2 WHERE bar=2;
Will produce:
Table | Count
---------------
Table1 | 1
Table2 | 2