Show values that occur certain number of times in particular column - sql

I'm trying to show values that meet my condition only, which is number of occurences-based.
Assuming the following table:
+--------------+----------------+
| account_id | campaign_id |
+--------------+----------------+
| 234 | 980 |
| 893 | 458 |
| 234 | 178 |
| 097 | 741 |
| 893 | 584 |
| 893 | 452 |
| 109 | 789 |
+--------------+----------------+
I need to show account_ids that only have two or more campaign_ids. So for the aforementioned table the result should be:
234
893
using count at where expression is not possible. I've used:
CASE WHEN count(account_id) >= 2
THEN es.entity_name
ELSE NULL
END AS Live_date
However, It got so many records have nothing to do with my query. Most of the related questions I found talk about finding the number of occurences rather than use it as a condition. Is there any other solution for this.

Please try using HAVING Clause:
select
account_id
From YourTable
group by account_id
having count(*)>=2

select account_id
from table
group by account_id
having count(*) >= 2

Related

new entries by one id

There is a table1 with fields call_id, param0, param1, param2, ...param30 .
The param fields take values ​​from 1 to 100.
And there is a second table table2 with fields call_id, theme_code
which Ineed to fill out from the first table,
The complexity of the task is that for one call_id I need to take each of these param as theme_code,
And if one of the param is null, then you don't need to create a new record for call_id
Example:
table1:
callid | par0 | par1 | par2 | par3 | par4 | par5 | par6 | par7 | par8 | par9 | par10 |
-------------------------------------------------------------------------------------------
1234567 | 24 | 2 | null | 91 | 58 | null | 25 | 19 | 77 | 62 | null |
table2:
callid | theme_code |
------------------------
1234567 | 24 |
------------------------
1234567 | 2 |
------------------------
1234567 | 91 |
------------------------
1234567 | 58 |
------------------------
1234567 | 25 |
------------------------
1234567 | 19 |
------------------------
1234567 | 77 |
------------------------
1234567 | 62 |
You seem to just want to unpivot the columns from table1 into multiple rows:
select callid, theme_code
from table1
unpivot (
theme_code
for par in (par0, par1, par2, par3, par4, par5, par6, par7, par8, par9, par10)
)
CALLID
THEME_CODE
1234567
24
1234567
2
1234567
91
1234567
58
1234567
25
1234567
19
1234567
77
1234567
62
fiddle
You can read more about pivoting and unpivoting in this article.
Unless table1 is some kind of staging table, copying that data into table2 would go against normalisation principles, and you might be better off just using that query when you need it, or creating a view based on it (which could be a materialised view).
If you really do want to put the unpivoted data into another table then you can use that query as the basis for an insert or merge statement.

How to trace back a record all the way to origin using SQL

We are a table called ticketing that tracks all the service tickets. One ticket can lead to another ticket which leads to another ticket indicated by the replaced_by_ticket_id field below
| ticket_id | is_current | replaced_by_ticket_id |
|-----------|------------|-----------------------|
| 134 | 0 | 240 |
| 240 | 0 | 321 |
| 321 | 1 | Null |
| 34 | 0 | 93 |
| 25 | 0 | 16 |
| 16 | 0 | 25 |
| 93 | 1 | Null |
How do I write a query to get the number of tickets leading to the current ones (321 & 93)? I mean I could join the table by itself, but there is no way of knowing how many times to join. Plus different tickets have different number of levels.
Here is the expected result of the query
| ticket_id | total_tickets |
|-----------|---------------|
| 321 | 3 |
| 93 | 4 |
What is the best way to do it?
You can use a recursive query; the trick is to keep track of the original "current" ticket, so you can aggregate by that in the outer query.
So:
with cte as (
select ticket_id, ticket_id as parent_id from ticketing where is_current = 1
union all
select c.ticket_id, t.ticket_id
from ticket t
inner join cte c on c.parent_id = t.replaced_by_ticket_id
)
select ticket_id, count(*) total_tickets
from cte
group by ticket_id

result of selecting field names from table with group by

Say you're given the following table called Customers:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Hardik | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Ramesh | 25 | Ahmedabad | 6500.00 |
| 5 | Hardik | 27 | Delhi | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Ramesh | 24 | Ahmedabad | 10000.00 |
+----+----------+-----+-----------+----------+
A lot of resources explaining group by statements would use an example like:
SELECT NAME, SUM(SALARY) FROM CUSTOMERS GROUP BY NAME; where the thing being 'selected' other than the field being 'grouped by' is a function like count or sum. But what happens if you did something like SELECT NAME, ADDRESS FROM CUSTOMERS GROUP BY NAME; - how exactly would the addresses be grouped together in a single record with the name. I know I can run this and find out the answer, but I want to understand the general logic - if anyone could assist that would be very much appreciated.
EDIT ANOTHER QUESTION:
In the new table above, if I did SELECT NAME, ADDRESS, group_concat(salary) FROM CUSTOMERS GROUP BY NAME; would this be ok, seeing as how the addresses are the same for each name?
If you say SELECT NAME, ADDRESS FROM CUSTOMERS GROUP BY NAME, you will get an error asking you to put an aggregation function around the ADDRESS column. For instance, you could write
SELECT NAME, MAX(ADDRESS) FROM CUSTOMERS GROUP BY NAME

Add running number in select statement based on a column

I have a view receipt_data that includes contract_no and receipt_no columns - something like this:
contract_no | receipt_no | Amount
------------+------------+---------
1176 | ABMN1024 | 100
1176 | ABMN1027 | 767
1176 | ABMN1027 | 345
NULL | MNDF7132 | 389
NULL | NULL | 673
1046 | MDGF2344 | 454
I need to query this view with running number added to it. Running number should be added as following.
run_no |contract_no | receipt_no | Amount
----------+------------+------------+--------
1 | 1176 | ABMN1024 | 100
2 | 1176 | ABMN1027 | 767
| 1176 | ABMN1027 | 345
3 | NULL | MNDF7132 | 389
| NULL | NULL | 673
4 |1046 | MDGF2344 | 454
The running number must be like
Add running number to unique contract_no + receipt_no
If receipt_no has value then return running number
If receipt_no is null, there's no need to add running number, skip it
Is it possible to script like this? Please help
you can try by using row_number() analytic function
select
case when receipt_no is not null
then
row_number()over(order by (select null))
else null end as run_no,t.* from
table_name t

SQL add new line if value is in second column also

So I am trying to pull the data from the table to give me each score the person has and if they have two scores I would like it to be on a new line with the second score. If the user has no scores I don't want anything returned. My query returns the first score if the user has one and if they don't it returns the second one. But if the user has two scores is where i'm not sure how to return that one on a new line.
table 1
+---------+--------+--------+
| name | score1 | score2 |
+---------+--------+--------+
| jim | null | 87 |
| doug | 21 | 45 |
| brandon | null | null |
| susy | 11 | null |
+---------+--------+--------+
The result my query gives is
+------+----+
| jim | 87 |
| doug | 21 |
| susy | 11 |
+------+----+
Wanted output
+------+----+
| jim | 87 |
| doug | 21 |
| doug | 45 |
| susy | 11 |
+------+----+
The query I wrote is
SELECT
name
,COALESCE(score1, score2)
FROM
table
WHERE
score1 IS NOT NULL
OR score2 IS NOT NULL
ORDER BY
name;
Treat this as two separate queries and combine the results together with UNION ALL. You'll want UNION ALL in this case and not just UNION so you get two rows returned in the case where the person has the same score in both columns.
SELECT name, Score1 as score
FROM table1
WHERE Score1 IS NOT NULL
UNION ALL
SELECT name, Score2 as score
FROM table1
WHERE Score2 IS NOT NULL
ORDER BY name, score;
I would recommend cross apply:
SELECT t.name, v.score
FROM table t CROSS APPLY
(VALUES (score1), (score2)) v(score)
WHERE v.score IS NOT NULL
ORDER BY name;
This is usually the most efficient way to unpivot data in SQL Server.