The query below:
SELECT i_adgroup_id, i_category_id
FROM adgroupcategories_br
WHERE i_adgroup_id IN
(
SELECT i_adgroup_id
FROM adgroupusers_br
WHERE i_user_id = 103713
)
GROUP BY i_adgroup_id, i_category_id;
Gives me results like this:
i_adgroup_id integer | i_category_id smallint
---------------------|-----------------------
15938 | 2
15938 | 3
15938 | 4
15942 | 1
15942 | 2
What I want is results like this:
i_adgroup_id integer | i_category_id smallint[]
---------------------|-----------------------
15938 | { 2, 3, 4 }
15942 | { 1, 2 }
How can I change the original SQL query to give me the result above?
You want to use array_agg, this should work:
SELECT i_adgroup_id, array_agg(i_category_id)
FROM adgroupcategories_br
WHERE i_adgroup_id IN
(
SELECT i_adgroup_id
FROM adgroupusers_br
WHERE i_user_id = 103713
)
GROUP BY i_adgroup_id;
Note that i_category_id is no longer in the GROUP BY as it is now being aggregated.
Related
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
I have an sqlite3 database with two tables that looks like this:
Table: Position
| pk | name | ...
------------------
| 1 | pos1 | ...
| 2 | pos2 | ...
Table: Status
| pk_position | datetime | ...
----------------------
| 1 | 20170201 | ...
| 1 | 20170204 | ...
| 1 | 20170205 | ...
| 1 | 20170207 | ...
| 2 | 20170204 | ...
| 2 | 20170201 | ...
| 2 | 20170208 | ...
Where datetime is "YYYYMMDD" (i.e. %Y%m%d) and pk_position is a ForeginKey of the table Position.
I need the following: given two intervals of time int1 = [day1:day2] and int2 = [day3:day4], I want a unique selection of pk_position for which there exists at least 1 row with datetime contained in each interval.
Examples (using example tables):
int1 = ["20170201" : "20170202"] and int2 = ["20170202" : "20170203"] => (null)
int1 = ["20170204" : "20170205"] and int2 = ["20170205" : "20170206"] => 1
int1 = ["20170203" : "20170204"] and int2 = ["20170204" : "20170205"] => 1, 2
I tried to use the EXISTS but I can't find any smart way to achieve this.
Thanks!
OBS: I tried to keep the question as broad as possible. In reality in all my use cases the intervals will have the form [day1 : day2], [day2 : day3] (i.e. they share a common boundary), just like all examples. If doing this for a common boundary is easier, I'll be happy with a solution to this simpler problem.
I think this will get you there (I don't have a way to test SQLite, so it wouldn't surprise me if there wasn't a missing comma, or the semicolons are wrong, or something like that, but this is the logic in SQL, adapted to SQLite as best I can without final testing):
CREATE TEMP TABLE
_time_intervals
(
int1 TEXT,
int2 TEXT,
int1Start TEXT,
int1End TEXT,
int2Start TEXT,
int2End TEXT
);
INSERT INTO
_time_intervals(int1, int2)
VALUES ( '["20170201" : "20170202"]', '["20170202" : "20170203"]' );
UPDATE _time_intervals
SET int1Start = SUBSTR(int1, 3, 8),
SET int1End = SUBSTR(int1, 16, 8),
SET int2Start = SUBSTR(int2, 3, 8),
SET int2End = SUBSTR(int2, 16, 8)
SELECT
pk_position
FROM
(
SELECT
s.pk_position,
1 AS int1_counter,
0 AS int2_counter
FROM
Status AS s
WHERE
s.datetime BETWEEN (SELECT int1Start FROM _time_intervals) AND (SELECT int1End FROM _time_intervals)
UNION ALL
SELECT
s.pk_position,
0 AS int1_counter,
1 AS int2_counter
FROM
Status AS s
WHERE
s.datetime BETWEEN (SELECT int2Start FROM _time_intervals) AND (SELECT int2End FROM _time_intervals)
) AS sq
GROUP BY
pk_position
HAVING
SUM(int1_counter) > 0
AND
SUM(int2_counter) > 0;
DROP TABLE _time_intervals;
I've got these two tables:
___Subscriptions
|--------|--------------------|--------------|
| SUB_Id | SUB_HotelId | SUB_PlanName |
|--------|--------------------|--------------|
| 1 | cus_AjGG401e9a840D | Free |
|--------|--------------------|--------------|
___Rooms
|--------|-------------------|
| ROO_Id | ROO_HotelId |
|--------|-------------------|
| 1 |cus_AjGG401e9a840D |
| 2 |cus_AjGG401e9a840D |
| 3 |cus_AjGG401e9a840D |
| 4 |cus_AjGG401e9a840D |
|--------|-------------------|
I'd like to select the SUB_PlanName and count the rooms with the same HotelId.
So I tried:
SELECT COUNT(*) as 'ROO_Count', SUB_PlanName
FROM ___Rooms
JOIN ___Subscriptions
ON ___Subscriptions.SUB_HotelId = ___Rooms.ROO_HotelId
WHERE ROO_HotelId = 'cus_AjGG401e9a840D'
and
SELECT
SUB_PlanName,
(
SELECT Count(ROO_Id)
FROM ___Rooms
Where ___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
) as ROO_Count
FROM ___Subscriptions
WHERE SUB_HotelId = 'cus_AjGG401e9a840D'
But I get empty datas.
Could you please help ?
Thanks.
You need to use GROUP BY whenever you do some aggregation(here COUNT()). Below query will give you the number of ROO_ID only for the SUB_HotelId = 'cus_AjGG401e9a840D' because you have this condition in WHERE. If you want the COUNTs for all Hotel_IDs then you can simply remove the WHERE filter from this query.
SELECT s.SUB_PlanName, COUNT(*) as 'ROO_Count'
FROM ___Rooms r
JOIN ___Subscriptions s
ON s.SUB_HotelId = r.ROO_HotelId
WHERE r.ROO_HotelId = 'cus_AjGG401e9a840D'
GROUP BY s.SUB_PlanName;
To be safe, you can also use COUNT(DISTINCT r.ROO_Id) if you don't want to double count a repeating ROO_Id. But your table structures seem to have unique(non-repeating) ROO_Ids so using a COUNT(*) should work as well.
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 do I select two most nearly fields to specific timestamp?
SELECT *
FROM 'wp_weather'
WHERE ( timestamp most nearly to 1385435000) AND city = 'Махачкала'
The table:
id | timestamp
---------------
0 | 1385410000
1 | 1385420000
2 | 1385430000
3 | 1385440000
4 | 1385450000
SELECT *
FROM wp_weather
WHERE city = 'Махачкала'
order by abs(timestamp - 1385435000)
limit 2
You may try like this:
SELECT * FROM 'wp_weather'
WHERE city = 'Махачкала'
order by abs(timestamp - 1385435000)
limit 2
Also check the ABS function