I am a newbie studying MSSQL and Database.
I am trying to write a SQL query to count values in the column.
Following table is original one.
name value
----------
A 1
A 1
A 2
B 1
B 2
I want to get a table like this.
name one two
--------------
A 2 1
B 1 1
A has two 1 and one 2 and B has one 1 and 2. It seems I can accomplish it using COUNT built-in function. I tried but failed. Is there any idea to do it?
use conditional aggregation
select name, sum(case when value=1 then 1 else 0 end) as one,
sum(case when value=2 then 1 else 0 end) as two
from table_name group by name
Related
I have two tables. Data in the first table is:
ID Username
1 Dan
2 Eli
3 Sean
4 John
Second Table Data:
user_id Status_id
1 2
1 3
4 1
3 2
2 3
1 1
3 3
3 3
3 3
. .
goes on goes on
These are my both tables.
I want to find the frequency of individual users doing 'status_id'
My expected result is:
username status_id(1) status_id(2) status_id(3)
Dan 1 1 1
Eli 0 0 1
Sean 0 1 2
John 1 0 0
My current code is:
SELECT b.username , COUNT(a.status_id)
FROM masterdb.auth_user b
left outer join masterdb.xmlform_joblist a
on a.user1_id = b.id
GROUP BY b.username, b.id, a.status_id
This gives me the separate count but in a single row without mentioning which status_id each column represents
This is called pivot and it works in two steps:
extracts the data for the specific field using a CASE statement
aggregates the data on users, to make every field value lie on the same record for each user
SELECT Username,
SUM(CASE WHEN status_id = 1 THEN 1 END) AS status_id_1,
SUM(CASE WHEN status_id = 2 THEN 1 END) AS status_id_2,
SUM(CASE WHEN status_id = 3 THEN 1 END) AS status_id_3
FROM t2
INNER JOIN t1
ON t2.user_id = t1._ID
GROUP BY Username
ORDER BY Username
Check the demo here.
Note: This solution assumes that there are 3 status_id values. If you need to generalize on the amount of status ids, you would require a dynamic query. In any case, it's better to avoid dynamic queries if you can.
Re-edited to make it clearer:
I would like my results to appear as they do in 'Column b' based on 'Column a' groupings? so a 1 or 0 per group based on column a. Column b does not exist currently, I am trying to code this in. I was trying to use row_number or rank but this not appear to work for me. So how do I write my SQL so I can get my SQL results to mirror Column b? Any help is appreciated
Thank - you
column a
column b
aaa
1
aaa
0
ddd
1
ddd
0
ddd
0
yyy
1
yyy
0
yyy
0
You just need to wrap your row_number() in a case, something like this:
select
column_a
case row_number() over (partition by column_a)
when 1 then 1
else 0
end as column_b
from
table
/
I'm trying to extract data from database with a particular template.
In my database I have the following data:
System | Type | Number
A TypeA 1
A TypeB 1
A TypeA 1
B TypeA 1
I'd like to get something like this:
System | #TypeA | #TypeB
A 2 1
B 1 0
Is it possible with only one query?
I tried to do full outer join between two queries without success. I'm curious to know the best solution in terms of performance.
Thank you in advance!
You can do this with aggregation using a conditional case expression
select system,
Sum(case when type='TypeA' then 1 else 0 end) "#TypeA",
Sum(case when type='Typeb' then 1 else 0 end) "#TypeB"
from t
group by system;
I have a table called "Scan" customer transactions where an individual_id appears once for every different transaction and contains column like scan_id.
I have another table called ids which contains random individual_ids sampled from Scan Table
I would like to join ids with scan and get a single record of ids and scan_id if it matches certain values.
Suppose data is like below
Scan table
Ids scan_id
---- ------
1 100
1 111
1 1000
2 100
2 111
3 124
4 1000
4 111
Ids table
id
1
2
3
4
5
I want below output i.e if scan_id matches either 100 or 1000
Id MT
------ ------
1 1
2 1
3 0
4 1
I executed below query and got error
select MT, d.individual_id
from
(
select
CASE
when scan_id in (90069421,53971306,90068594,136739913,195308160) then 1
ELSE 0
END as MT
from scan cs join ids r
on cs.individual_id = r.individual_id
where
base_div_nbr =1
and
country_code ='US'
and
retail_channel_code=1
and visit_date between '2019-01-01' and '2019-12-31'
) as d
group by individual_id;
I would appreciate any suggestions or help with regard to this Hive query. If there is an efficient way of getting this job done. Let me know.
Use a group by:
select s.individual_id,
max(case when s.scan_id in (100, 1000) then 1 else 0 end) as mt
from scan s
group by s.individual_id;
The ids table doesn't seem to be needed for this query.
I have a table with data as shown below (the table is built every day with current date, but I left off that field for ease of reading).
This table keeps track of people and the doors they enter on a daily basis.
Table entrance_t:
id entrance entered
------------------------
1 a 0
1 b 0
1 c 0
1 d 0
2 a 1
2 b 0
2 c 0
2 d 0
3 a 0
3 b 1
3 c 1
3 d 1
My goal is to report on people and count entrances not used(grouping on people), but ONLY if they entered(entered=1).
So using the above table, I would like the results of query to be...
id count
----------
2 3
3 1
(id=2 did not use 3 of the entrances and id=3 did not use 1)
I tried queries(some with inner joins on two instances of same table) and I can get the entrances not used, but it's always for everybody. Like this...
id count
----------
1 4
2 3
3 1
How do I not display results id=1 since they did not enter at all?
Thank you,
You could use conditional aggregation:
SELECT id, count(CASE WHEN entered = 0 THEN 1 END) AS cnt
FROM entrance_t
GROUP BY id
HAVING count(CASE WHEN entered = 1 THEN 1 END) > 0;
DBFiddle Demo