SQL select counts on 1 value - sql

I have a table like this:
+---------+------------+--------+--------------+
| Id | Name | Status | Content_type |
+---------+------------+--------+--------------+
| 2960671 | PostJob | Error | general_url |
| 2960670 | auto_index | Done | general_url |
| 2960669 | auto_index | Done | document |
| 2960668 | auto_index | Error | document |
| 2960667 | auto_index | Error | document |
+---------+------------+--------+--------------+
And I want to count how many of each type that has 'Error' as status, so in the result it would be 1x general_url and 2x document
I tried something like this:
SELECT COUNT(DISTINCT Content_type) from Indexing where Status = 'Error';
But I could not figure out how to get the content_type out of it

You want this
select Content_type,
count(Status)
from Indexing
where Status='Error'
group by Content_type;

GROUP BY should do the job:
SELECT Content_type, COUNT(Id) from Indexing where Status = 'Error' GROUP BY Content_type;
Explanation:
COUNT (x) counts the number of rows in the group, COUNT (*) would do the same.
COUNT (DISTINCT x) counts the number of distinct values in the group.
Without a GROUP BY clause the group is the whole set of records, so in your example you would have seen a single value (2) as your result; i.e. there are 2 distinct Content_types in the set.

SQL Fiddle Oracle
Schema
create table test
(id varchar2(10),
name varchar2(30),
status varchar2(20),
content_type varchar2(30)
);
insert into test values('2960671','PostJob','Error','general_url');
insert into test values('2960670','auto_index','Done','general_url');
insert into test values('2960669','auto_index','Done','document');
insert into test values('2960668','auto_index','Error','document');
insert into test values('2960667','auto_index','Error','document');
Select Query
SELECT LISTAGG(content_type, ',') WITHIN GROUP (ORDER BY rownum) AS content_type,
count(content_type) as content_type_count
from
(
select distinct(content_type) content_type
FROM test
where status='Error'
);
Output
| CONTENT_TYPE | CONTENT_TYPE_COUNT |
|----------------------|--------------------|
| document,general_url | 2 |
The idea here is to print comma separated content_type values so that you can know the count of content_type along with actual values

Try this One
SELECT count(`content_type`) as 'count', content_type as 'x content type' FROM `tablename` where status= 'Error' group by(`content_type`)

Related

How to get a value inside of a JSON that is inside a column in a table in Oracle sql?

Suppose that I have a table named agents_timesheet that having a structure like this:
ID | name | health_check_record | date | clock_in | clock_out
---------------------------------------------------------------------------------------------------------
1 | AAA | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:25:07 |
| | "physical":{"other_symptoms":"headache", "flu":"no"}} | | |
---------------------------------------------------------------------------------------------------------
2 | BBB | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:26:12 |
| | "physical":{"other_symptoms":"no", "flu":"yes"}} | | |
---------------------------------------------------------------------------------------------------------
3 | CCC | {"mental":{"stress":"no", "depression":"severe"}, | 6-Dec-2021 | 08:27:12 |
| | "physical":{"other_symptoms":"cancer", "flu":"yes"}} | | |
Now I need to get all agents having flu at the day. As for getting the flu from a single JSON in Oracle SQL, I can already get it by this SQL statement:
SELECT * FROM JSON_TABLE(
'{"mental":{"stress":"no", "depression":"no"}, "physical":{"fever":"no", "flu":"yes"}}', '$'
COLUMNS (fever VARCHAR(2) PATH '$.physical.flu')
);
As for getting the values from the column health_check_record, I can get it by utilizing the SELECT statement.
But How to get the values of flu in the JSON in the health_check_record of that table?
Additional question
Based on the table, how can I retrieve full list of other_symptoms, then it will get me this kind of output:
ID | name | other_symptoms
-------------------------------
1 | AAA | headache
2 | BBB | no
3 | CCC | cancer
You can use JSON_EXISTS() function.
SELECT *
FROM agents_timesheet
WHERE JSON_EXISTS(health_check_record, '$.physical.flu == "yes"');
There is also "plain old way" without JSON parsing only treting column like a standard VARCHAR one. This way will not work in 100% of cases, but if you have the data in the same way like you described it might be sufficient.
SELECT *
FROM agents_timesheet
WHERE health_check_record LIKE '%"flu":"yes"%';
How to get the values of flu in the JSON in the health_check_record of that table?
From Oracle 12, to get the values you can use JSON_TABLE with a correlated CROSS JOIN to the table:
SELECT a.id,
a.name,
j.*,
a."DATE",
a.clock_in,
a.clock_out
FROM agents_timesheet a
CROSS JOIN JSON_TABLE(
a.health_check_record,
'$'
COLUMNS (
mental_stress VARCHAR2(3) PATH '$.mental.stress',
mental_depression VARCHAR2(3) PATH '$.mental.depression',
physical_fever VARCHAR2(3) PATH '$.physical.fever',
physical_flu VARCHAR2(3) PATH '$.physical.flu'
)
) j
WHERE physical_flu = 'yes';
db<>fiddle here
You can use "dot notation" to access data from a JSON column. Like this:
select "DATE", id, name
from agents_timesheet t
where t.health_check_record.physical.flu = 'yes'
;
DATE ID NAME
----------- --- ----
06-DEC-2021 2 BBB
Note that this approach requires that you use an alias for the table name (so you can use it in accessing the JSON data).
For testing I used the data posted by MT0 on dbfiddle. I am not a big fan of double-quoted column names; use something else for "DATE", such as dt or date_.

Count string occurances within a list column - Snowflake/SQL

I have a table with a column that contains a list of strings like below:
EXAMPLE:
STRING User_ID [...]
"[""null"",""personal"",""Other""]" 2122213 ....
"[""Other"",""to_dos_and_thing""]" 2132214 ....
"[""getting_things_done"",""TO_dos_and_thing"",""Work!!!!!""]" 4342323 ....
QUESTION:
I want to be able to get a count of the amount of times each unique string appears (strings are seperable within the strings column by commas) but only know how to do the following:
SELECT u.STRING, count(u.USERID) as cnt
FROM table u
group by u.STRING
order by cnt desc;
However the above method doesn't work as it only counts the number of user ids that use a specific grouping of strings.
The ideal output using the example above would like this!
DESIRED OUTPUT:
STRING COUNT_Instances
"null" 1223
"personal" 543
"Other" 324
"to_dos_and_thing" 221
"getting_things_done" 146
"Work!!!!!" 22
Based on your description, here is my sample table:
create table u (user_id number, string varchar);
insert into u values
(2122213, '"[""null"",""personal"",""Other""]"'),
(2132214, '"[""Other"",""to_dos_and_thing""]"'),
(2132215, '"[""getting_things_done"",""TO_dos_and_thing"",""Work!!!!!""]"' );
I used SPLIT_TO_TABLE to split each string as a row, and then REGEXP_SUBSTR to clean the data. So here's the query and output:
select REGEXP_SUBSTR( s.VALUE, '""(.*)""', 1, 1, 'i', 1 ) extracted, count(*) from u,
lateral SPLIT_TO_TABLE( string , ',' ) s
GROUP BY extracted
order by count(*) DESC;
+---------------------+----------+
| EXTRACTED | COUNT(*) |
+---------------------+----------+
| Other | 2 |
| null | 1 |
| personal | 1 |
| to_dos_and_thing | 1 |
| getting_things_done | 1 |
| TO_dos_and_thing | 1 |
| Work!!!!! | 1 |
+---------------------+----------+
SPLIT_TO_TABLE https://docs.snowflake.com/en/sql-reference/functions/split_to_table.html
REGEXP_SUBSTR https://docs.snowflake.com/en/sql-reference/functions/regexp_substr.html

Return an array(Repeated Field) from a query in BigQuery

I am new to BigQuery and SQL. I have a table with following details
Schema
ID : String : Nullable
BCats : String : Repeated
ID can be repeated
Preview
ID BCats
|-----------------------|
| ABCD | BCat25 |
| | BCat24 |
| | BCat23 |
|_______________________|
| PQRS | BCat8 |
| | BCat9 |
|_______________________|
| ABCD | BCat23 |
| | BCat25 |
| | BCat24 |
|_______________________|
| MNOP | BCat12 |
| | BCat13 |
|_______________________|
| PQRS | BCat8 |
| | BCat9 |
|-----------------------|
I am trying to group the table based on ID using the following query
Query
SELECT BCats,ID
FROM (SELECT (GROUP_CONCAT(BCats)) as BCats,ID
FROM(
SELECT
UNIQUE(BCats) as BCats,ID FROM
my_table
GROUP BY
ID
)
GROUP BY
ID
)
OUTPUT from the query in JSON Format is
Output from Query
{"BCats":"BCat25,BCat24,BCat23","ID":"ABCD"}
{"BCats":"BCat8,BCat9","ID":"PQRS"}
{"BCats":"BCat12,BCat13","ID":"MNOP"}
My question is how can I output Array from the Query, like this
Expecting Output
{"BCats" : ["BCat25","BCat24","BCat23"],"ID":"ABCD"}
Currently I am getting BCats as a String.
I need to output this data into new table with BCats as Repeated.
Please Help.
Preview :
Try below. Note: in Web UI you need not only set Destination Table but also set/check-on Allow Large Results checkbox and uncheck Flatten Results checkbox
SELECT NEST(UNIQUE(BCats)) AS BCats, ID
FROM my_table
GROUP BY ID
You should instead use standard SQL. If you are familiar with legacy SQL, there is a migration guide that talks about the differences between the two dialects. After enabling standard SQL (uncheck "Use Legacy SQL" under "Show Options" in the UI) you can run e.g.:
WITH my_table AS (
SELECT 'ABCD' AS ID, ['BCat25', 'BCat24', 'BCat23'] AS BCats UNION ALL
SELECT 'PQRS', ['BCat8', 'BCat9'] UNION ALL
SELECT 'ABCD', ['BCat23', 'BCat25', 'BCat24'] UNION ALL
SELECT 'MNOP', ['BCat12', 'BCat13'] UNION ALL
SELECT 'PQRS', ['BCat8', 'BCat9']
)
SELECT
ID,
ARRAY_AGG(DISTINCT BCat) AS BCats
FROM my_table, UNNEST(BCats) AS BCat
GROUP BY ID;

Search an SQL table that already contains wildcards?

I have a table that contains patters for phone numbers, where x can match any digit.
+----+--------------+----------------------+
| ID | phone_number | phone_number_type_id |
+----+--------------+----------------------+
| 1 | 1234x000x | 1 |
| 2 | 87654311100x | 4 |
| 3 | x111x222x | 6 |
+----+--------------+----------------------+
Now, I might have 511132228 which will match with row 3 and it should return its type. So, it's kind of like SQL wilcards, but the other way around and I'm confused on how to achieve this.
Give this a go:
select * from my_table
where '511132228' like replace(phone_number, 'x', '_')
select *
from yourtable
where '511132228' like (replace(phone_number, 'x','_'))
Try below query:
SELECT ID,phone_number,phone_number_type_id
FROM TableName
WHERE '511132228' LIKE REPLACE(phone_number,'x','_');
Query with test data:
With TableName as
(
SELECT 3 ID, 'x111x222x' phone_number, 6 phone_number_type_id from dual
)
SELECT 'true' value_available
FROM TableName
WHERE '511132228' LIKE REPLACE(phone_number,'x','_');
The above query will return data if pattern match is available and will not return any row if no match is available.

How to find every customers' favourite category with a query

I have a table in MS Access which looks basically like this:
Table Name : Customer_Categories
+----------------------+------------+-------+
| Email | CategoryID | Count |
+----------------------+------------+-------+
| jim#example.com | 10 | 4 |
+----------------------+------------+-------+
| jim#example.com | 2 | 1 |
+----------------------+------------+-------+
| simon#example.com | 5 | 2 |
+----------------------+------------+-------+
| steven#example.com | 10 | 16 |
+----------------------+------------+-------+
| steven#example.com | 5 | 3 |
+----------------------+------------+-------+
In this table there are ≈ 350,000 records. The characteristics are this:
Duplicate values for Email, CategoryID and Count
Count refers to the number of times this customer has ordered from this category
What I want
I want to create a table that consists of a unique email address along with the CategoryID this customer has purchased from the most.
So the above example would be:
+----------------------+------------+
| Email | CategoryID |
+----------------------+------------+
| jim#example.com | 10 |
+----------------------+------------+
| simon#example.com | 5 |
+----------------------+------------+
| steven#example.com | 10 |
+----------------------+------------+
What I have tried
I have written a query that achieves what I want:
SELECT main.Email, (SELECT TOP 1 CategoryID
FROM Customer_Categories
WHERE main.Email = Email
GROUP BY CategoryID
ORDER BY MAX(Count) DESC, CategoryID ASC) AS Category
FROM Customer_Categories AS main
GROUP BY main.Email;
This works a treat and does exactly what I want. It returns results in around 8 seconds. However I need this data in a new table because I then want to update another table with the categoryID. When I add INTO Customer_Favourite_Categories after the sub-query to add this data to a new table rather than just return the result set and run the query it never finishes. I've left it running for about 45 minutes and it does nothing.
Is there any way around this?
If select into doesn't work, use insert into:
create table Customer_Favorite_Categories (
email <email type>,
FavoriteCategory <CategoryId type>
);
insert into Customer_Favorite_Categories
SELECT main.Email, (SELECT TOP 1 CategoryID
FROM Customer_Categories
WHERE main.Email = Email
GROUP BY CategoryID
ORDER BY MAX(Count) DESC, CategoryID ASC) AS Category
FROM Customer_Categories AS main
GROUP BY main.Email;
Try this:
SELECT Distinct(Email),Max(CategoryID )
FROM Customer_Categories group by Email
I use sub-queries for this quite frequently. Your query in "What I have tried" is close, but just a little off in syntax. Something like the following should get what you are after. Count is in square-brackets since it's a reserved word in SQL. The spacing I use in my SQL is conventional, so edit to your liking.
SELECT Email,
CategoryID
FROM MyTable AS m,
(
SELECT Email,
MAX( [Count] ) AS mc
FROM MyTable
GROUP BY Email
) AS f
WHERE m.Email = f.Email
AND m.[Count] = f.mc;