Join select statements to get columns in SQL - sql

SELECT COUNT(Type) from House where Type = 1
SELECT COUNT(Type) from House where Type = 2
SELECT COUNT(Type) from House where Type = 3
My question is: I want to join the above 3 statements to get: 3 columns i.e. eg:
ColumnType1: '50', ColumnType2: '60', columnType3: '45'
thanks

You can create the columns using an aggregate function with a CASE expression:
SELECT
count(case when Type = 1 then Type end) as type_1,
count(case when Type = 2 then Type end) as type_2,
count(case when Type = 3 then Type end) as type_3
from House

You can use a case and add up if the Type matches
SELECT sum(case when Type = 1 then 1 else 0 end) as type_1,
sum(case when Type = 2 then 1 else 0 end) as type_2,
sum(case when Type = 3 then 1 else 0 end) as type_3
from House

There is a cleaner type of SQL which can give you this answer, but you will have each type on a different row:
SELECT Type, COUNT(Type) FROM House GROUP BY Type
It has the disadvantage of not giving you columns as you asked for; but the advantage is that it works for any number of different types without needing to change the query.

SELECT
COUNT(Type) as val1,
(SELECT COUNT(Type) from House where Type = 2) as val2,
(SELECT COUNT(Type) from House where Type = 3) as val3
from House where Type = 1

Related

SQL query - group by string prefix

I'm struggling with a grouping query.
I have simple table named CarParts where some car elements stored in it.
Some of those elements are available (with Type prefix "05") and some are blocked (Type prefix "01").
I want to write select query that would group my table CarParts by SerialNr and Type as shown below on the right side.
Do you want conditional aggregation?
select serialnr, name,
sum(case when type like '%-05' then amount else 0 end) as [05-available],
sum(case when type like '%-01' then amount else 0 end) as [01-blocked]
from carparts
group by serialnr, name;
You can use PIVOT to get your desired result as below-
SELECT SerialNr,
ISNULL([05-Available],0) [05-Available],
ISNULL([01-Available],0) [01-Available],
Name
FROM
(
SELECT SerialNr,Amount,Name,RIGHT( Type,2) +'-Available' AS P_Column
FROM CarParts
) AS P
PIVOT
(
SUM(Amount)
FOR P_Column IN ([01-Available],[05-Available])
) AS PVT
you can use case when
select SerialNr,Name,
sum(case when right([Type],2)='01' then amount else 0 end) as blocked_01
sum(case when right([Type],2)='05' then amount else 0 end) as availabe_05
from tbale_name group by SerialNr,Name
select SerialNr,
sum(case when Type like '%-05' then Amount else 0 end) as '05-available',
sum(case when Type like '%-01' then Amount else 0 end) as '01-blocked',
Name
from carparts
group by SerialNr, Name

How to write a sql to select records with specific conditions

Need to select from a same column based on specific conditions from a same table
I tried using max case when status =‘OP’ then tot_amountelse 0
Max case when status =‘PR’ and curr_flag =‘Y’ thentot_amount else 0
Below is the table
ID Type Status tot_Amount curr_flag
1 Null OP 100 N
1. F. PR 60 N
1. H. PR. 0. Y
Expected output
ID Type. TotalAmt Bal-Amt
1. H. 100. 0
You want conditional aggregation :
select id,
max(case when curr_falg = 'Y' then Type end) as Type,
sum(case when Status = 'OP' then tot_Amount else 0 end) as TotalAmt,
sum(case when Status = 'PR' and curr_falg = 'Y' then tot_Amount else 0 end) as Bal_Amt
from table t
group by id;

Creating a New Table in Big Query from a log table and a reference table

I am new to big query and need to create a perm. table from a log file and a reference table. I am new to this, and did something wrong but can't figure out why. Please help.
log file (example)
-Event_Time,User_ID,Type
-1/1/2017,123_abc,a
-1/2/2017,123_bcd,b
-1/2/2017,123_abc,c
Reference Table (example)
-Type Partner
-a 1
-b 2
-c 3
-d 3
create table workarea.SummaryTable AS (
User_ID string,
TotalCount integer,
imps_time timestamp,
Partner integer)
insert into workarea.SummaryTable
select distinct User_ID,
COUNT(*) as TotalCount,
MIN(TIME) as imps_time,
SUM(case when Partner = '1' then 1 else 0 end) as 1,
SUM(case when Partner = '2' then 1 else 0 end) as 2,
SUM(case when Partner = '3' then 1 else 0 end) as 3
from workarea.logfile i
join workarea.referencetable r on i.Type=r.Type
where CID=10848805
group by USER_ID
.. and did something wrong but can't figure out why
Below points of failure I have identified so far
CREATE TABLE statement is not available in BigQuery
Data Manipulation Language allows you INSERT, DELETE and UPDATE only
You need to have table pre-created before you can manipulate with / insert data in it
Aliases cannot start with digits -
so below fragment is incorrect
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS 1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS 2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS 3
you should rather use something like
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS Partner_1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS Partner_2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS Partner_3
Some fields look like do not exist in referenced tables but you use them in final query: time in MIN(time) as imps_time and CID in WHERE CID=10848805
Schema of destination table has 4 fields - whereas schema of select statement has 6 fields. You should clear this out!! They must match!
Possible "solution" (BigQuery Standard SQL)
I assume (just for a sake of getting some progress here) the schema of your destination table in reality as something as below
User_ID STRING,
TotalCount INT64,
imps_time TIMESTAMP,
Partner_1 INT64,
Partner_2 INT64,
Partner_3 INT64
in this case - below query should produce correct result for insertion
#standardSQL
SELECT
User_ID,
COUNT(*) AS TotalCount,
MIN(Event_Time) AS imps_time,
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS Partner_1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS Partner_2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS Partner_3
FROM `workarea.logfile` i
JOIN `workarea.referencetable` r ON i.Type=r.Type
-- WHERE CID=10848805
GROUP BY USER_ID

Make a grouping and transforming query Oracle

I have a test table:
category   type  quantities
 a      1    100
 a      2    150
 b      2    45
 b      3    68
 b      1    72
 c      2    90
 c      3    39
It is assume that only 3 types appeared. My goal is select out there categories, and quantities of each type. Result should like:
category   type1   type2   type3
 a      100    150    0
 b      72     45    68
 c      0     90    39
I'm trying with union, but I think it is redundant and not briefness:
select category, sum(type1)type1, sum(type2)type2 ,sum(type3) type3 from
(
select category, sum(quantities) type1, 0 type2, 0 type3 from test where type=1 group by category
union all
select category, 0 type1, sum(quantities) type2, 0 type3 from test where type=2 group by category
union all
select category, 0 type1, 0 type2, sum(quantities) type3 from test where type=3 group by category
) group by category;
What can I do to shorten my query? Thank you for any suggestions.
That is simple conditional aggregation:
select
category,
nvl(sum(case when type = 1 then quantities end), 0) as type1,
nvl(sum(case when type = 2 then quantities end), 0) as type2,
nvl(sum(case when type = 3 then quantities end), 0) as type3
from mytable
group by category
order by category;
Also known as a pivot table -- see http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html

Counting all other types but the current one

I'm trying to write this query, that would calculate the average value of all the columns except the one that contains the type value, which I'm grouping the whole query by.
So for 4 types for example, each column in the resulting table will contain the average of all the other three type's values, i need to exclude the current type's rows.
As an example, if I was to calculate each type's average value for itself, the query would look like:
SELECT
SUM(some value) / COUNT(TYPE)
FROM TEMPTABLE
GROUP BY TYPE
Now I'm trying to calculate the other three's total average. Thanks.
You can do one query to get the distinct types, and LEFT JOIN the same table, checking for type-inequality:
SELECT t1.type,
SUM(t2.some_value) / COUNT(t2.type)
FROM ( SELECT DISTINCT type FROM temptable ) t1
LEFT JOIN temptable t2 ON ( t1.type <> t2.type )
GROUP BY t1.type
Since you only want the average, you could replace the line
FROM ( SELECT DISTINCT type FROM temptable ) t1
by
FROM temptable t1
but the first solution might perform better, since the number of rows is reduced earlier.
The starting point here is to make a cartesian join between your types and your temptable (guessing your tables structure is : type(id, type), valueTable(id, type_id, some_value))
The following query
SELECT t.type, SUM(vt.someValue) /
COUNT (*) AS sum FROM type t,
valueTable vt WHERE vt.type_id != t.id
GROUP BY t.type
should do the trick.
Will this do what you need?
(Possibly with another CASE statement to avoid divide by zero errors if there is a possibility none of a type might be returned, I've also not explicitly accounted for the case that type is NULL)
SELECT
SUM(CASE WHEN TYPE <> 'Type1' THEN someValue ELSE 0 END) /
SUM(CASE WHEN TYPE = 'Type1' THEN 1 ELSE 0 END) AS T1,
SUM(CASE WHEN TYPE <> 'Type2' THEN someValue ELSE 0 END) /
SUM(CASE WHEN TYPE = 'Type2' THEN 1 ELSE 0 END) AS T2,
SUM(CASE WHEN TYPE <> 'Type3' THEN someValue ELSE 0 END) /
SUM(CASE WHEN TYPE = 'Type3' THEN 1 ELSE 0 END) AS T3,
SUM(CASE WHEN TYPE <> 'Type4' THEN someValue ELSE 0 END) /
SUM(CASE WHEN TYPE = 'Type4' THEN 1 ELSE 0 END) AS T4
FROM TEMPTABLE
I think that you can just use this:
SELECT type, avg(col_01)
FROM myTable
GROUP BY type
Should work on Sybase too:
SELECT
SUM(some value) / SUM(CASE WHEN TYPE = 1 THEN 1 ELSE 0 END)
FROM TEMPTABLE
GROUP BY TYPE