Managing JOINS in Google Query Language (Google Sheets) - sql

I am trying to get a simple recount of how many penalties each user accumulates in my company's website, but avoiding the users that have been deleted (my rows are static, but the new rows added each week have updated user info)
So I have this:
penalty_id date user user_status
1 22/09 aaa active
2 23/09 bbb active
3 23/09 ccc active
4 01/10 bbb active
5 02/10 aaa deleted
And I would like to have this:
user pentaly_count
bbb 2
ccc 1
So far I have come up with this
=query(Penalties!A:D;"select C, count(A) where D !='deleted' group by C label C 'user', count(A) 'penalty_count'")
So I end up with this:
user pentaly_count
bbb 2
aaa 1*
ccc 1
The query skips the count of penalty with id 5, but I want it to skip user aaa entirely.
I could have managed this in SQL doing a simple subquery or even a join, but everything I come up with, Google Sheets says it does not work.

Please try this
select C, count(A)
group by C
having min(case when D ='deleted' then 1 end) is null
label C 'user', count(A) 'penalty_count'

Related

Access Select Values from another value based on the current table value

I have 2 Tables in Access and I am trying to build a LookUp Query. (I am new to SQL)
Dogs
ID
DogName
Type (int) Either 1,2,3,4
ClassResults
ID
ClassEntered (int) 1-24
DogName
So in my lookup I am trying to find all the dogs from the DOGS table that if the ClassEntered is less than 12 select all the dogs with a TYPE 1 or 2.
Dogs Data Sample:
ID DogName Type
0 AAA 1
1 BBB 3
2 CCC 1
3 DDD 2
4 EEE 4
ClassResults Data Sample:
ID ClassEntered DogName
0 6 ?????
So, the Drop Downlist for the DogName should be Showing:
0, AAA, 1
2, CCC, 1
3, DDD, 2
SELECT DISTINCT Dogs.DogName FROM Dogs, ClassResults
WHERE (IIf([ClassResults].[ClassEntered] < 10,[Dogs.Type]<3,[Dogs.Type]>2)) ORDER BY Dogs.DogName;
SELECT DISTINCT Dogs.DogName FROM Dogs, ClassResults
WHERE (IIf([ClassResults].[ClassEntered] < 10,[Dogs.Type]<3,[Dogs.Type]>2)) ORDER BY Dogs.DogName;
I hope that makes sense.
Stephan
It's better to use joins:
select * from dogs d
left join ClassResults c on d.dogname=c.dogname
where c. ClassEntered<12 and d.type in (1,2)
If you want to pick data from two different tables, you have to utilize joins.

SQL - Counting unique rows based on a separate field

I am trying to count unique values on a per user basis and end up with a combined count. They may exist more than once per user, but should only be counted once per user.
Example:
user value
1 AAA
1 AAA
1 BBB
1 CCC
2 AAA
2 CCC
2 CCC
3 AAA
3 BBB
3 BBB
3 BBB
Expected result with count:
AAA 3
BBB 2
CCC 2
So values should only be counted once per user, no matter how many times they are present.
I have gotten as far as counting the total number of values with this:
SELECT value, COUNT(value) FROM table GROUP BY value")
But this counts all instances of each value, I cannot work out how to count only the unique values per user and the combine. Hope this makes sense! Many thanks!
Try this:
SELECT value, COUNT(distinct user) FROM table GROUP BY value

How to count entries in sql "like in a loop"

First thing, I'm very new to databases so this is probably a very simple question, but I didn't know how to google it or how to give it a good title. I'm using postgres from python, but the problem is to put together the right query.
The scenario is the following. I hava a table with columns: ID, Trial, Subject, Invalid. It comes from a behavioral experiment where many subjects perform a task that is composed of several trials. Their responses can be invalid for different reasons, and depending on the reason there is a different invalidation code (an integer). A valid response has code 0.
------------------------------
ID | SUBJECT | TRIAL | INVALID
------------------------------
1 Peter 1 0
2 Peter 2 0
3 Peter 3 1
4 Peter 4 3
5 Mary 1 3
6 Mary 2 2
7 Mary 3 0
8 Mary 4 2
I would like to do two things (which I'm not sure how to do in an elegant way).
a) For each subject, I would like to know how many responses are in total and how many are valid. Now I'm making a query for each subjects, with the condition, e.g., WHERE Subject='Peter', but I can imagine that there is a more elegant solution.
Sample answer:
Subject Valids Total
Peter 2 4
Mary 1 4
b) For each subjects, I would like to know how many responses were invalid for each of the invalidation codes. Ideally I would get a table like:
Subject Invalid Count
Peter 0 2
Peter 1 1
Peter 2 0
Peter 3 1
Mary 0 1
Mary 1 0
Mary 2 2
Mary 3 1
Query #1: You want one result row per subject, so you group by subject. Use COUNT to count all records for a subject and COUNT in combination with CASE to count conditionally (all valid ones).
select
subject,
count(*) as all_responses,
count(case when invalid = 0 then 1 end) as valid_responses
from mytable
group by subject;
Query #2: Here you want one result row per subject and code, so you group by these two. Then count with COUNT.
select
subject,
invalid,
count(*) as responses
from mytable
group by subject, invalid;
UPDATE: In your updated request you want query #2 to show all subject/code combinations even if they have a count of 0. In order to do this, you'd have to create the set of all valid combinations first and then outer join your response table:
select
s.subject,
c.code,
count(m.invalid) as responses
from subjects s
cross join codes c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;
If you don't have tables for subjects and code (which you should), you can get them from your responses table instead:
select
s.subject,
c.code,
count(m.invalid) as responses
from (select distinct subject from mytable) s
cross join (select distinct invalid as code from mytable) c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;

SQL SERVER - Change column value if value exists

I have the following problem.
Imagine I get the following return table from a select statement
Column A Column B
100 aaa
100 bbb
100 ccc
200 ddd
300 eee
So the question is, how can I change my SQL Select statement to add a new column that shows the numbers of times the Column A has a repeat value. The problem is that I need to get some subgrups with an order.
For example, it should return something like:
Column A Column B Column C
100 aaa 1
100 bbb 2
100 ccc 3
200 ddd 1
300 eee 1
Thank you very much for your support!
This is the classic usecase for the analytic RANK() function:
SELECT a, b, RANK() OVER (PARTITION BY a ORDER BY b) AS c
FROM my_table
Add ROW_NUMBER() OVER (PARTITION BY ColA ORDER BY SomethingElse) as ColC. That gives you a sequential row number per "group" in ColA.

SSIS- how to split 1 record into multiples record

I have table below:
SerialNumber Name Product
1 aaa a
2 bbb b
3 ccc c
I would like to convert to table below:
serialNumber PropertyName value
1 Name aaa
1 Product a
2 Name bbb
2 Product b
3 Name ccc
3 Product c
How can i achieve this in SSIS 2012?
You have Pivot and Unpivot Data Flow Transformations, but even simpler it will be for you to use Multicast, to make two streams out of one. Then in one stream you'll be passing Names and values, an in the other Products and values. Then use Union All to join the streams again.