I am trying to make a system where you can search posts based on tags (using a SQL db).
Example schema:
Post: id, name
Tag: id, name, post_id (foreign_key)
Example Object:
Posts:
{
"id": 1,
"name": "Post1"
}
{
"id": 2,
"name": "Post2"
}
Tags:
{
"id": 1,
"name": "Tag1",
"post_id": 1
}
{
"id": 2,
"name": "Tag2",
"post_id": 1
}
{
"id": 3,
"name": "Tag1",
"post_id": 2
}
Example, I search with Tag1 and Tag2
I want to get back a list with relevance (how many tags matched).
Example:
{
"post_id": 1,
"tag_count": 2
}
{
"post_id": 2,
"tag_count": 1
}
Id started with:
select * from recipes_tag where name in ("tag1", "tag2")
But I can't find a way to count by the post_id to see how many tags each post has in the search.
SQL uses ' to quote strings.
Then you can just use aggregation to count the tags...
SELECT
post_id,
COUNT(DISTINCT name) AS count_of_tags
FROM
recipes_tag
WHERE
name IN ('tag1', 'tag2')
GROUP BY
post_id
If you want to ensure there are at least a certain number of matches, add this to the end...
HAVING
COUNT(DISTINCT name) = 2
Related
I have cosmos DB with a container having multiple documents. I want to get all the ids with the same value of a property. Since it's Cosmos I cannot use the having clause.
eg: If there is a container with the schema,
{
"id": 1,
"source": "online",
"type": "login"
},
{
"id": 1,
"source": "online",
"type": "login"
},
{
"id": 2,
"source": "online",
"type": "login"
},
{
"id": 2,
"source": "In store",
"type": "login"
}
I want all the ids where the source value is all same and "online". So in the above example, it should return "id" as 1 only.
This request selects all IDs that did not have other source types at all, only those online
select distinct(id), source
from(
select id, source
from your_table as t
WHERE NOT EXISTS (SELECT id
FROM your_table
WHERE source != 'online'
AND your_table.id = t.id))x
-- If need at the end use this WHERE x.id IS NOT NULL
Result :
| id | source
|:---- |:------:
| 1 | online
I have two tables: users table with id, name columns and events table with id, content and userId columns.
I am trying to query a table that return joined information from these two tables with name and events columns where events would represent an array of content fields corresponding to a user.
This is the query I am running:
select
name, group_concat(content) as events
from
users
left join
events on id = userId
group by
userId
order by
id
However rows with null values are not being returned except of just one row. What am I doing wrong?
Users table
[
{
"id": 1,
"name": "Hugo Powlowski"
},
{
"id": 2,
"name": "Jeremy Littel II"
},
{
"id": 3,
"name": "Eleanor King"
},
{
"id": 4,
"name": "Rogelio Jacobson"
},
{
"id": 5,
"name": "Jerald Rowe PhD"
},
{
"id": 6,
"name": "Robyn Tromp"
},
{
"id": 7,
"name": "Norman Zboncak"
},
{
"id": 8,
"name": "Mr. Kristy Orn"
},
{
"id": 9,
"name": "Mrs. Olivia Trantow"
},
{
"id": 10,
"name": "Daniel Lebsack"
}
]
Events table
[
{
"eventId": 3,
"content": "hello",
"userId": 7
},
{
"eventId": 12,
"content": "rulsan berden",
"userId": 1
}
]
Joined table
[
{
"name": "Hugo Powlowski",
"events": "rulsan berden"
},
{
"name": "Jeremy Littel II",
"events": null
},
{
"name": "Norman Zboncak",
"events": "hello"
}
]
You should group by the column in the parent table, not the table being left joined, so that the values will never be null.
So change GROUP BY userid to GROUP BY users.id.
Try to use a nested SELECT, this should return null for the users without any event:
select
u.name,
SELECT(
group_concat(content)
FROM
events
WHERE
userId = u.id
) as events
from
users u
order by
u.id
I have a list of Conversations, that come from multiple pages as below:
[
{
"id": 1,
"page_id": 1,
"name": "name 1",
"assigned_user_ids": ["user1"]
},
{
"id": 2,
"page_id": 2,
"name": "name 2",
"assigned_user_ids": ["user2"]
},
{
"id": 3,
"page_id": 1,
"name": "name 3",
"assigned_user_ids": ["user2"]
},
{
"id": 4,
"page_id": 2,
"name": "name 4",
"assigned_user_ids": ["user1"]
}
]
Imagine that "User 1" is calling the query, and User 1 can get all items of page_id = 1 (because user 1 is administrator), but in page_id = 2 he/she
only get the items that has been assigned to, in this case is item with id = 4.
So when user 1 query, what I want to received is:
[
{
"id": 1,
"page_id": 1,
"name": "name 1",
"assigned_user_ids": ["user1"]
},
{
"id": 3,
"page_id": 1,
"name": "name 3",
"assigned_user_ids": ["user2"]
},
{
"id": 4,
"page_id": 2,
"name": "name 4",
"assigned_user_ids": ["user1"]
}
]
This is my existing query in SQL look like:
SELECT * FROM Conversations
WHERE PageId IN (1, 2)
Can any one tell me how to modify my SQL to resolve my problem?
Thank you very much!
You can use OR It will either give you what is on page one, so everything from there, or everything that has been assigned to userId 1. So effectively only the things that have been assigned on every other page.
SELECT * FROM Conversations
WHERE PageId = 1 OR userId = 1
If you want to restrict this to only some pages, you can still use IN.
SELECT * FROM Conversations
WHERE PageId = 1 OR userId = 1 AND pageId IN (2,3,4)
I have a jsonB field in postgresql DB table, it has data like this
{
"units": [
{
"id": 299872379221376,
"unitNumber": "1",
"unitFloorSpace": 1,
"createdTimeStamp": 1587994498586
},
{
"id": 299872417011074,
"unitNumber": "2",
"unitFloorSpace": 2,
"createdTimeStamp": 1588001330085
}
]
}
I just want to list all unitNumbers like below, what would be the query for that?
1,
2,
I have tried below json query but that doesn’t list
Select form_data -> units -> unitNumbers from table where row_id =1;
here is one way:
select jsonb_array_elements(jsonb_extract_path(jdata,'units')) ->> 'unitNumber' as UnitNumber
from tableName;
db<>fiddle here
Is it possible to have a RavenDb faceted search, in a string[] field, where I would want to show facets (counts) for only values starting with a particular string, rather a range?
I'll try to explain myself better to with a simple example, imagine having an index with the below entries
ID | Values
-------------------------
1 | CatPersian, CatNormal, DogLabrador
2 | CatPersian, Camel, DogPoodle
3 | CatNormal, CatBengali, DogNormal
4 | DogNormal
I would perform a query on the above documents, and the Facet search would include a range of 'Cat*', on the 'Values' field. Is this possible? Then, I would get a result based on just the different values for cats, like:
CatPersian [2]
CatNormal [2]
CatBengali [1]
Yes, you can do that. Index the array, and then just use facets normally.
Let's see the full example. You have the following documents:
{
"Name": "John",
"FavoriteAnimals": [
"Cats",
"Dogs",
"Snails"
],
"#metadata": {
"#collection": "Kids"
}
}
{
"Name": "Jane",
"FavoriteAnimals": [
"Cats",
"Rabits"
],
"#metadata": {
"#collection": "Kids"
}
}
Now, you create the following index:
from k in docs.Kids
from animal in k.FavoriteAnimals
select new { Animal = animal }
And run this query:
from index 'YourIndex'
where startsWith(Animal , 'ca')
select facet('Animal')
And the result will be:
{
"Name": "Animal",
"Values": [
{
"Count": 2,
"Range": "cats"
}
]
}
Alternatively, you can use this index:
from k in docs.Kids
select new { k.FavoriteAnimals }
And run this query:
from index 'YourIndex'
where startsWith(FavoriteAnimals , 'ca')
select facet('FavoriteAnimals')
The difference here is that you'll get all matches for the documents that have a match.
So in this case
{
"Name": "Animal",
"Values": [
{
"Count": 2,
"Range": "cats"
},
{
"Count": 1,
"Range": "dogs"// also, snails, rabbits
}
]
}