Count when event = 'birthday' and distinct user id - count

I can produce a query that looks at this separately but when I try and combine it I'm having an issue.
Original example query
Select account_name, count(distinct user_id)
from table
where event like 'birthday'
group by account name
Any help greatly appreciated
When I try and combine this in a larger query that looks at multiple event types I'm having trouble getting it to count distinct users
What I'm trying
Select account_name,
case when event_text = 'birthday' then count(distinct user_id) end
case when event_text = 'wedding' then count(distinct user_id) end
case when event_text = 'wedding' then count(distinct user_id) end
from table
group by account_name

Well looking at your current code you are firstly comparing with the column event and after with event_text.
As you said the first query did work the second query should be
case when event = 'birthday' then count(distinct user_id) end instead of case when event_text = 'birthday' then count(distinct user_id) end
also you should look into the OR operator : https://www.w3schools.com/sql/sql_and_or.asp
which should definitely be used for comparing 1 value from the same column with multiple values

If it is one table, you can try the following:
SELECT account_name, event, COUNT(*)
FROM table
GROUP BY account_name, event;
At the end of the query you could add an optional ORDER BY clause:
ORDER BY account_name
If you add this line of code you should put the semicolon from after the GROUP BY statement to the end behind the ORDER BY statement.

Related

Get LIMIT value from subquery result

I would like to use the LIMIT option in my query, but the number of expected rows is stored in another table. This is what I have, but it doesn't work:
select * from table1 limit (select limitvalue from table2 where id = 1)
When I only run the subquery, the result is 6, as expected.
I prefer working with a WITH statement if possible, but that didn't work eiter.
Thank you in advance!
You could use a prepared statement to get the limit of queries from the other table because the limit clause does not allow non constant variables as parameter:
PREPARE firstQuery FROM "SELECT * FROM table1 LIMIT ?";
SET #limit = (select limitvalue from table2 where id = 1);
EXECUTE firstQuery USING #limit;
The source of the sql query from another post
You can make use of MariaDB's ROW_NUMBER function in a CTE to count the rows to be output, comparing that against the limitvalue. For example:
WITH rownums AS (
SELECT *,
ROW_NUMBER() OVER () AS rn
FROM table1
)
SELECT *
FROM rownums
WHERE rn <= (SELECT limitvalue FROM table2 WHERE id = 1)
Note Using LIMIT without ORDER BY is not guaranteed to give you the same results every time. You should include an ORDER BY clause in the OVER part of the ROW_NUMBER window function. With the sample data in my demo, you might use something like:
ROW_NUMBER() OVER (ORDER BY mark DESC)
Demo on dbfiddle

BigQuery - How to order by event

I'm starting using BigQuery these days for work. Until now I managed to request what I wanted but I'm stuck.
I retrieve data from Firebase on my big query console. These data are events from a mobile game we are testing.
I would like to know how many players are there in each level by ABVersion. I can't figure out how to do it.
I did this:
SELECT
param.value.string_value AS Version,
COUNT (DISTINCT user_pseudo_id) AS Players,
param2.value.string_value AS Level
FROM
`*Name of the dataset*`,
UNNEST(event_params) AS param,
UNNEST(event_params) AS param2
WHERE
event_name = 'Level_end'
AND param.key = 'ABVersion'
AND param2.key = 'Level'
GROUP BY Version,Level
And I got this:
I would like to have the number of players per level, with the ABVersion provided.
Thank you for your help!
Level is an integer parameter instead of string. So you should use value.int_value for level.
For the thing you're trying to do, it looks like a better query to me:
SELECT
highest_level,
abversion,
count(*) as players
FROM (
SELECT
user_pseudo_id,
ANY_VALUE((SELECT value.string_value FROM UNNEST(params) WHERE key = 'ABVersion')) as abversion,
MAX((SELECT value.int64_value FROM UNNEST(params) WHERE key = 'Level')) as highest_level
FROM `*Name of the dataset*`,
WHERE
event_name = 'Level_end'
AND EXISTS (SELECT 1 FROM UNNEST(params) WHERE key IN ('Level', 'ABVersion'))
GROUP BY user_pseudo_id
)
GROUP BY 1,2
ORDER BY 1,2

How to be sure about All events have 'Sesssion Info' like ga_session_id, ga_session_number IN NEW PROPERTY APP+WEB for GA

i'm try to verify whether All events have 'session info' in new property App+Web using BigQuery.
here is the sample data schema of my table.
event_params.key got ga_session_id
than i tried this query.
#standardSQL
SELECT
event_name, COUNT(event_name) as count_event_name
FROM
`mytable`,
UNNEST(event_params) AS params
WHERE params.key = "ga_session_id"
in this query, I got 24,473,721 rows in total, which seems to have "ga_session_id"
but, because the mytable have 24,753,258 rows, so there are at lease 279,537 rows which have no "ga_session_id".
So i want to know which event_name have no "ga_session_id", and how many of it.
Any possible codes? please help :'(
ADD)
Adding '!' to WHERE is not a solution(i've tried)
Because UNNESTing adds an additional rows. it results more than 189 million rows which exceed original table row.
#standardSQL
SELECT
event_name, COUNT(event_name) as count_event_name
FROM
`mytable`,
UNNEST(event_params) AS params
WHERE params.key != "ga_session_id"
thanks
As you say, using UNNEST generates a lot of rows. This is because for each original row (same event_name), you have one row generated per each event_params "subrow".
When you do the unnesting, those 24,753,258 rows are unnested into a lot more (of the order of 200 million).
From those, 24473721 meet the condition params.key = "ga_session_id", and about 189 million don't (that's why they appear in the != clause).
What you have to keep in mind is that for a same event (which is identified with a timestamp and name), when you apply the unnest operator lots of rows are generated, so with your query you are counting each event more than once.
Having said that, if what you want to do is to know how many events contain the "ga_session_id", you should do a query like this
#standardSQL
SELECT
event_name, COUNT(DISTINCT event_timestamp) as number_of_each_event_name
FROM
`mytable`,
UNNEST(event_params) AS params
WHERE params.key = "ga_session_id"
GROUP BY event_name
And if you want to do the contrary, you can apply the != condition
If you want to get the total number of events that meet the condition, without splitting them according to the event_name, your query is this one:
#standardSQL
SELECT
COUNT(DISTINCT event_timestamp) as total_number_of_events
FROM
`mytable`,
UNNEST(event_params) AS params
WHERE params.key = "ga_session_id"
The result of this query, added to the result of the same query with the != condition, should be now 24,753,258, which was the original number of rows (events) you had in your table.
I hope this works for you!

Why did I get the ""exact fetch returns more than requested number of rows" when I use cursor already?

I am using the cursor to write the following codes, so that the cursor can pick up multiple lines. However, it still gives me the error message "exact fetch returns more than requested number of rows". Isn't that the cursor will retrieve data one line at a time. Why is this message still showing?
create or replace trigger e
before delete on enrollment
for each row
declare
get_tid scorest.tid%type;
get_ferm scorest.ferm%type;
get_sect scorest.sect%type;
get_name scorest.name%type;
get_score scorest.score%type;
cursor findenrolls(atid in scorest.tid%type,
aferm in scorest.ferm%type,
asect in scorest.sect%type)
is select * from scorest;
begin
for findenrolls_rec in findenrolls(:old.tid, :old.ferm, :old.sect) loop
select tid, ferm, sect, name, score
into get_tid, get_ferm, get_sect, get_name, get_score
from scorest
where scorest.tid=:old.tid
and scorest.ferm=:old.ferm
and scorest.sect=:old.sect;
insert into deleted_scores values (get_tid, get_ferm, get_sect, get_name, get_score);
delete from scorest
where tid=get_tid
and ferm=get_ferm
and sect=get_sect
and name=get_name;
end loop;
end;
Your error come from this statement part. select into must return exact one record.
select tid, ferm, sect, name, score
into get_tid, get_ferm, get_sect, get_name, get_score
from scorest
where scorest.tid=:old.tid
and scorest.ferm=:old.ferm
and scorest.sect=:old.sect;
You must rewrite your code make it work. Without knowing you use case it can be harder, but you can try this.
CREATE OR REPLACE
TRIGGER e before DELETE
ON enrollment
FOR EACH row
BEGIN
FOR get IN (
SELECT tid
, ferm
, sect
, name
, score
FROM scorest
WHERE scorest.tid=:old.tid
AND scorest.ferm =:old.ferm
AND scorest.sect =:old.sect
)
LOOP
INSERT
INTO deleted_scores VALUES
( get.tid
, get.ferm
, get.sect
, get.name
, get.score
);
DELETE
FROM scorest
WHERE tid=get.tid
AND ferm =get.ferm
AND sect =get.sect
AND name =get.name;
END LOOP;
END;
How you can see the explicit cursor is gone and replaced by an implicit one, this look more appropriate for this case.
error is coming due to duplicate data in scorest table based on tid , ferm ,sect
you can check this by
select tid , ferm ,sect from scorest having count(1)>1
group by tid , ferm ,sect;
if you don't need duplicates when you can put one more condition in your select statement
select tid, ferm, sect, name, score
into get_tid, get_ferm, get_sect, get_name, get_score
from scorest
where scorest.tid=:old.tid
and scorest.ferm=:old.ferm
and scorest.sect=:old.sect;
and rownum =1
else you can which to approach suggested by "Ftaveras ".

How to filter old entries with unique id out of SQL query

I have a table and a relation
I have maybe 10 Submissions, but when I query the database I only want to get those with a Unique CaseId and the one to return should be the one with the newest Date. Is it possible (And adviceable) to do this in a single query or should I do the filtering in my asp.nets code behind where I fetch the data?
Edit: New images
Here you can see that I show many items with the same case id, I only want to show the latest one (Based on date)
This is my current sql query
SELECT Submission.Id, Date, center.Name as CenterName, center.Id as CenterId, subject.Name as SubjectName, subject.Id as SubjectId, EmployeeName, Reason, Description, Explanation, Done, ChiefLevel, Action, CaseId
FROM Submission, subject, center
WHERE center.Id=CenterId AND subject.Id=SubjectId
ORDER BY Date DESC;
SELECT caseid
FROM
(
SELECT caseid, max(date) AS max_date
FROM submission
GROUP BY caseid
) a
JOIN subject t ON a.subjectid=t.id
My QUERY ended up being this
SELECT s.Id, s.Date, c.Name as CenterName, c.Id as CenterId, su.Name as SubjectName, su.Id as SubjectId, s.EmployeeName, s.Reason, s.Description, s.Explanation, s.Done, s.ChiefLevel, s.Action, s.CaseId
FROM submission as s
INNER JOIN
(
SELECT CaseId, MAX(Date) AS MaxDateTime
FROM submission
GROUP BY CaseId
) as groupeds
ON s.CaseId = groupeds.CaseId
AND s.`Date` = groupeds.MaxDateTime
INNER JOIN
(
SELECT Id, Name
FROM subject
) as su
ON su.Id=SubjectId
INNER JOIN
(
SELECT Id, Name
FROM center
) as c
ON c.Id=CenterId;

Resources