SQL QUERY HELP — Count the frequency of associated values given an input value - sql

[HELP]
Hi everyone,
I have this table with the following columns:
id
textID
value
1
1
Hedonic
2
1
Negative feelings
3
2
Hedonic
4
2
Negative feelings
5
2
Fun
6
2
Motivation
7
3
Enjoy
8
3
Hedonic
9
3
Fun
10
4
Negative feelings
11
4
Pain
And what I want to do is return the frequency of values associated with a given input value.
For example, given the value 'Hedonic', I want to return the count of values associated where 'hedonic' exists.
With the data from the table presented above, it should return the following table, for input 'Hedonic':
value
count
Hedonic
3
Negative feelings
2
Fun
2
Enjoy
1
Motivation
1
Can anyone help me?
I have no idea how to perform the SQL query... I've tried several approaches, but still no success.
Thank you very much

One method uses exists:
select value, count(*)
from t
where exists (select 1
from t t2
where t2.textid = t.textid and t2.value = 'Hedonic'
)
group by value;

Related

SQL - Update in a cross apply query

UPDATE Table1
SET SomeColumn = X.SomeOtherColumn
FROM Table1 T1
CROSS APPLY
(SELECT TOP 1 SomeOtherColumn
FROM Table2 T2
WHERE T2.SomeJoinColumn = T1.SomeJoinColumn
ORDER BY CounterColumn) AS X
I want to increase CounterColumn by 1 each time the cross apply query runs. Is there any way I could achieve this?
Some context and sample data
I have a table containing information about companies. I want to anonymize the company numbers in this table. To do this, I want to use data from another table, containing synthetized data. This table has a much smaller sample size. So I have to reuse the same synthetic companies multiple times. For each row in the table I anonymize, I want to pick a synthetic company of the same type. I want to use all the synthetic companies. That's where the counter comes in, counting how many times I've used that specific synthetic company. By sorting by this counter, I was hoping to be able to always pick the synthetic company that's been used the least.
Company table (Table1)
CompanyNumber
Type
67923
2
82034
2
90238
7
29378
2
92809
5
72890
2
Synthetic company table (Table2)
SyntheticCompanyNumber
Type
Counter
08366
5
0
12588
2
0
33823
2
0
27483
7
0
Expected output of Company table:
CompanyNumber
Type
12588
2
33823
2
27483
7
12588
2
08366
5
33823
2
Expected output of synthetic company table
SynteticCompanyNumber
Type
Counter
08366
5
1
12588
2
2
33823
2
2
27483
7
1

Is there a more efficient way of selecting the data than multiple intersects SQL

I have data in my PostgreSQL database in the format below
answer_id question_id country_id answer
1 1 1 7
2 1 2 7
3 1 3 5
4 2 1 3
5 2 2 2
6 2 3 2
What I am trying to do is get all countries which have a certain answer for a certain country, and we can have multiple question~answer combination.
For example I can need all countries which for question 1 have 7 for an answer (2 values), but then, along with the first condition) I also add that answer for question 2 is 2 and now it drops from 2 values (countries under ids 1 and 2) to only 1 (country id 2).
Now I have managed to do it with intersect as it follows...
select country_id from answer_table where question_id = 1 and answer = 7
intersect
select country_id from answer_table where question_id = 2 and answer = 2
Problem is that I need to be able to do this dynamically, meaning that one time I may select only 1 question~answer pair, but other times I may want more (3, 5, 7 or whatever) which affects the number of selects (and in turn intersects).
I mean this above works and I do have a capability to use a query builder so it really isn't a big deal to generate, but I don't believe that it is the most efficient nor the smartest way.
Therefore, my question is basically is there a more efficient or smarter way of doing these selects/intersects dynamically (like function which takes arrays of data or whatever?)?
Thank You and have a good one!
p.s. I found this stack thread, but there they use fixed 5 queries at all times.
I don't know if it is more efficient, but you might find it more generalizable:
select country_id from answer_table
where (question_id, answer) in ( (1, 7), (2, 2) )
group by country_id
having count(distinct (question_id, answer) ) = 2;
You can actually replace the in list and "2" with array functions to pass in array values.

Access SQL query select with a specific pattern

I want to select each 5 rows to be unique and the select pattern applies for the rest of the result (i.e if the result contains 10 records I am expecting to have 2 set of 5 unique rows)
Example:
What I have:
1
1
5
3
4
5
2
4
2
3
Result I want to achieve:
1
2
3
4
5
1
2
3
4
5
I have tried and searched a lot but couldn't find anything close to what I want to achieve.
Assuming that you can somehow order the rows within the sets of 5:
SELECT t.Row % 5, t.Row FROM #T t
ORDER BY t.Row , t.Row % 5
We could probably get closer to the truth with more details about what your data looks like and what it is you're trying to actually do.
This will work with the sample of data you provided
SELECT DISTINCT(thevalue) FROM theresults
UNION ALL
SELECT DISTINCT(thevalue) FROM theresults
But it's unclear to me if it's really what you need.
For instance :
if your table/results returns 12 rows, do you still want 2x5 rows or do you want 2x6 rows ?
do you have always in your table/results the same rows in double ?
There's a lot more questions to rise and no hint about them in what you asked.

Same entity from different tables/procedures

I have 2 procedures (say A and B). They both return data with similar columns set (Id, Name, Count). To be more concrete, procedures results examples are listed below:
A:
Id Name Count
1 A 10
2 B 11
B:
Id Name Count
1 E 14
2 F 15
3 G 16
4 H 17
The IDs are generated as ROW_NUMBER() as I don't have own identifiers for these records because they are aggregated values.
In code I query over the both results using the same class NameAndCountView.
And finally my problem. When I look into results after executing both procedures sequentially I get the following:
A:
Id Name Count
1 A 10 ->|
2 B 11 ->|
|
B: |
Id Name Count |
1 A 10 <-|
2 B 11 <-|
3 G 16
4 H 17
As you can see results in the second set are replaced with results with the same IDs from the first. Of course the problem take place because I use the same class for retrieving data, right?
The question is how to make this work without creating additional NameAndCountView2-like class?
If possible, and if you don't really mind about the original Id values, maybe you can try having the first query return even Ids :
ROW_NUMBER() over (order by .... )*2
while the second returns odd Ids :
ROW_NUMBER() over (order by .... )*2+1
This would also allow you to know where the Ids come from.
I guess this would be repeatable with N queries by having the query number i selecting
ROW_NUMBER() over (order by .... )*n+i
Hope this will help

Finding contiguous regions in a sorted MS Access query

I am a long time fan of Stack Overflow but I've come across a problem that I haven't found addressed yet and need some expert help.
I have a query that is sorted chronologically with a date-time compound key (unique, never deleted) and several pieces of data. What I want to know is if there is a way to find the start (or end) of a region where a value changes? I.E.
DateTime someVal1 someVal2 someVal3 target
1 3 4 A
1 2 4 A
1 3 4 A
1 2 4 B
1 2 5 B
1 2 5 A
and my query returns rows 1, 4 and 6. It finds the change in col 5 from A to B and then from B back to A? I have tried the find duplicates method and using min and max in the totals property however it gives me the first and last overall instead of the local max and min? Any similar problems?
I didn't see any purpose for the someVal1, someVal2, and someVal3 fields, so I left them out. I used an autonumber as the primary key instead of your date/time field; but this approach should also work with your date/time primary key. This is the data in my version of your table.
pkey_field target
1 A
2 A
3 A
4 B
5 B
6 A
I used a correlated subquery to find the previous pkey_field value for each row.
SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m;
Then put that in a subquery which I joined to another copy of the base table.
SELECT
sub.pkey_field,
sub.target,
sub.prev_pkey_field,
prev.target AS prev_target
FROM
(SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m) AS sub
LEFT JOIN YourTable AS prev
ON sub.prev_pkey_field = prev.pkey_field
WHERE
sub.prev_pkey_field Is Null
OR prev.target <> sub.target;
This is the output from that final query.
pkey_field target prev_pkey_field prev_target
1 A
4 B 3 A
6 A 5 B
Here is a first attempt,
SELECT t1.Row, t1.target
FROM t1 WHERE (((t1.target)<>NZ((SELECT TOP 1 t2.target FROM t1 AS t2 WHERE t2.DateTimeId<t1.DateTimeId ORDER BY t2.DateTimeId DESC),"X")));