Given a table events
sensor_id | event_type | value | time
----------+------------+--------+------------
2 |2 | 3.45 | 2014-02 (...)
2 |4 | (...) | (...)
2 |2 | (...) | (...)
3 |2 | (...) | (...)
2 |3 | (...) | (...)
Write an SQL query that returns a set of all sensors_id with the number of different event_types registered by each of them, ORDER BY sensor_id ASC
Query should return the following rowset
sensor_id | type
----------+------------
2 |3
3 |1
The names of the columns in the rowest don't matter, but their order does
My query:
SELECT
sensor_id, COUNT(*) AS `types`
FROM
`events`
GROUP BY
sensor_id
ORDER BY
sensor_id ASC
And result:
sensor_id | types
----------+------------
2 |4 <= error
3 |1
use distinct event_Type inside count
SELECT
sensor_id, COUNT(distinct event_type) AS `types`
FROM
`events`
GROUP BY
sensor_id
ORDER BY
sensor_id ASC
You can use window function:
select distinct sensor_id, types from (
SELECT
sensor_id, COUNT(distinct event_type) over(partition by sensor_id) AS `types`
FROM
`events` ) X
ORDER BY
sensor_id ASC;
Try this:
SELECT sensor_id, COUNT(DISTINCT event_type) as type
FROM #tbltemp
GROUP BY sensor_id
ORDER BY sensor_id
If you do not include count distinct value it will count no 2 two times (2,2,3,4).
If you put distinct it will count as (2,3,4) only.
Related
I got stuck in a problem and need help on this
I have a table like this:
created_time_id | txn_src
1-1-2017 | A
1-1-2017 | A
1-1-2017 | B
1-1-2017 | A
1-1-2017 | C
2-1-2017 | A
2-1-2017 | C
2-1-2017 | B
2-1-2017 | A
3-1-2017 | A
3-1-2017 | A
3-1-2017 | C
In redshift, I have to create a moving average column for the above table along with the source count partition by date
currently I have written the below query
select
txn_src,
created_time_id::char(8)::date as "time",
count_payment
from
(
select
txn_src,
created_time_id,
count(1) as count_payment,
row_number() over (partition by created_time_id
order by
count(1) desc) as seqnum
from
my_table
where
created_time_id >= '1-1-2017' and txn_source is not null
group by
1,
2
) x
where
seqnum <= 10
order by
"time" ,
count_payment desc
This gives me the correct output like
1-1-2017 | A | 3
1-1-2017 | B | 1
and so on
I need moving average like this
time |src|cnt|mvng_avg
1-1-2017 | A | 3 |3
1-1-2017 | B | 1 |1
1-1-2017 | C | 1 |1
2-1-2017 | A | 2 |2.5
and so on ..
Can anybody suggest some good solution for this.
After some struggle, I was able to resolve this using below query.
with txn_source_by_date as (
select
txn_source ,
created_time_id,
count(1) as count_payment,
row_number() over (partition by created_time_id
order by
count(1) desc) as seqnum
from
my_table
where
created_time_id >= 20220801
and txn_source is not null
group by
1,
2
)
select
txn_source,
created_time_id::char(8)::date as "time",
count_payment,
avg(count_payment) over (partition by txn_source
order by
created_time_id rows between 29 preceding and current row ) mvng_avg
from
txn_source_by_date
group by
txn_source,
created_time_id,
count_payment
order by
"time",
txn_source
I have some problem with how to build a query to sum all duplicates, in this query below I can count all occurrences.
SELECT COUNT (*) occurrences
FROM back.submission s
GROUP BY s.name
HAVING COUNT(*) > 1
----------
|# |occurrences|
|1 | 9 |
|2 | 6 |
|3 | 5 |
|4 | 4 |
|5 | 4 |
|6 | 3 |
....
I would like to know how to sum all occurrences, i tried to put count inside SUM, but it doesn't work
Do you want an other level of aggregation?
SELECT COUNT(occurences) AS count_of_duplicates, SUM(occurences) AS sum_of_duplicates
FROM (
SELECT COUNT (*) occurrences
FROM back.submission s
GROUP BY s.name
HAVING COUNT(*) > 1
) t
SELECT #,count(*) As Total FROM back.submission GROUP BY # HAVING COUNT(*) > 1;
With CTE
As
(
Select [#],Count([*]) As Total From back.submission Group By [#]
)
select [#],Total From CTE Where Total>1
I have a table like this:
--------------------------------------
RecID|name |date
--------------------------------------
1 |John | 05/09/2016
2 |John | 05/02/2016
3 |Mary | 05/09/2016
4 |Mary | 05/08/2016
5 |Mary | 03/02/2016
and I want to get the count for name for each instance in which that name has appeared on or before that date in the row. So I want the output to look like this:
--------------------------------------
RecID|name |date |count
--------------------------------------
1 |John | 05/09/2016 | 2
2 |John | 05/02/2016 | 1
3 |Mary | 05/09/2016 | 3
4 |Mary | 05/08/2016 | 2
5 |Mary | 03/02/2016 | 1
Any ideas on how I should go about doing this?
You can use the count function with a window specification.
select t.*, count(*) over(partition by name order by date) as cnt
from tablename t
This will produce incorrect results if there are mutliple rows on a given date for a name. One way to avoid this is using a correlated sub-query.
select t.*,
(select count(distinct t2.date)
from tablename t2
where t2.name=t.name and t2.date<=t.date) as cnt
from tablename t
Or use row_number.
select t.*, row_number() over(partition by name order by date) as cnt
from tablename t
Or use dense_rank if there can be multiple rows for the same name on a given date.
select t.*, dense_rank() over(partition by name order by date) as cnt
from tablename t
The easiest solution of all would be to use dense_rank.
use
count(*) count
and
group by date
if your date is already a string (i.e. without hour/minute information)
I have data in table like this:
UserData table:
|ID| Name | TeamName |
| 1| Peter | Alpha |
| 1| Peter | Beta |
| 1| Peter | Gamma |
| 2| Mary | Gamma |
| 2| Mary | Omega |
| 3| John | Kappa |
| 3| John | Delta |
Combinations of Name and TeamName are always unique. I need for each unique ID and Name get the top 1 TeamName and number of Team relations, like this:
table #FinalTable
|ID| Name | TeamName | NumberOfRelations |
| 1| Peter | Alpha | 3 |
| 2| Mary | Gamma | 2 |
| 3| John | Kappa | 2 |
Question - is there a way of doing this in one query, or do I have to use temporary tables for selection top 1 team and for counting number of relations and then select data indo separate final table?
I tried something like this:
;WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY TeamName Asc) AS rn
FROM UserData
)
SELECT * into #tempTable1
FROM cte
WHERE rn = 1
and this:
insert into #tempTable2 (ID, Name, NumberOfRelations)
select ID, Name, count(*) as NumberOfRelations
from UserData
group by ID, Name
...and then selecting data from two temp tables.
I wonder if there's more simple way of doing it.
For SQLserver:
You don't have order by,so i choose one below...
select top 1 with ties id,playen,count(id) over (partition by id,playen) as countt
,temaname
from #temp t1
order by row_number() over (partition by id,playen order by id,playen,temaname)
Output:
id playen countt temaname
1 Peter 3 Alpha
2 Mary 2 Gamma
3 John 2 Delta
Assuming this is SQL Server try this :
Select t.ID, t.Name, team.TeamName, count(t.TeamName) countt
from #temp t join
(Select id, TeamName, Row_Number() over (Partition By ID Order By TeamName asc) as rn
from #temp) team on (team.ID = t.ID and team.rn=1)
Group by t.ID, t.Name, team.TeamName
SQL tables represent unordered sets. There is no first team name, unless a column specifies the ordering. You don't seem to have such a column.
If you had such a column:
WITH cte AS (
SELECT ud.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ??) as seqnum,
COUNT(*) OVER (PARTITION BY ID) as cnt
FROM UserData ud
)
SELECT cte.*
FROM cte
WHERE seqnum = 1;
Note the ??. This is to specify the ordering for getting the team name. Depending on the database, you can use NULL or (SELECT NULL) to get an arbitrary team name.
I have a table with 10 columns and I am interested in 3 of those.
Say tableA with id, name, url, ranking.
id |name |url |ranking
--------------------------------
1 |apple |a1.com |1
2 |apple |a1.com |2
3 |apple |a1.com |3
4 |orange |o1.com |1
5 |orange |o1.com |2
6 |apple |a1.com |4
So, what I want is, all the columns for row with id 5 and 6. That would be row with maximum ranking for each group (apple, orange)
Use row_number to number the rows in each name group by their ranking in the descending order and select the the first row per each group.
select id,name,url,ranking
from
(select t.*, row_number() over(partition by name order by ranking desc) as rn
from tablename t) t
where rn =1