I'm having two tables (relation between themTest_case.id = Test_tag.test_id) like this:
Test_case table
id
name
1
Test name 1
2
Test name 2
3
Test name 3
4
Test name 4
Test_tag table
test_id
tag
1
feature:example1
1
package:Reports
1
QA
2
feature:example1
2
package:Reports
2
QA
3
feature:example1
3
package:Reports
3
QA
4
feature:newexample1
4
package:Charts
4
QA
The database tables and structure were already defined as I'm using a oublic library to push the results.
So, I need to return in the result the count of the id's and the value feature:example1
knowing that is a test that contains the tag package:Reports
So, it should return something like
Results
count(id)
tag
3
feature:example1
I already tried some different approaches without success.
How can I do that?
I think I'm as confused as everyone else, but this is a shot in the dark based on the various comments. There are much easier ways to arrive at this dataset, but I'm trying to read between the lines on your comments:
select
count (t.test_id), t.tag
from
test_case c
join test_tag t on c.id = t.test_id
where
t.tag like 'feature%' and
exists (
select null
from test_tag t2
where t2.test_id = t.test_id and t2.tag = 'package:Reports'
)
group by
t.tag
I'm looking to create a report of sorts and am having a hard time wrapping my head around how this portion could be done with a single select in SQL (my experience is limited to a database course and some working knowledge - more of a front end dev).
I should mention that joining the question table and question tag bindings/tags table isn't an issue for me - what I can't wrap my head around is how multiple values could be added to the same result cell without multiple nasty T-SQL loops.
Any tips on how to get started would be a huge help.
Table 1: Question Table
ID Content CategoryName
---------------------------
1 ABC Q1
2 DEF Q3
3 GEH Q3
Table 2: Tag Table
Tag Id Tag Name
---------------------------------
4 Dream
5 Light
6 Recover
Table 3: Question Tag Bindings
BoundQuestion ID BoundTagId
---------------------------------
1 4
2 5
3 6
3 4
Desired Result Table (Question table with added Tags column)
ID Content CategoryName Tags
----------------------------------------
1 ABC Q1 Dream
2 DEF Q3 Light
3 GEH Q3 Recover, Light
Thanks to anybody who looks at this, hope you're all staying safe.
You could join the three tables and aggregate to generate tag list. I guess that a lateral join should also be an efficient option here, since it avoids outer aggregation:
select q.*, t.*
from questions q
outer apply(
select string_agg(tag_name, ', ') tags
from questionTags qt
inner join tags t on t.TagID = qt.BoundTagID
where qt.BoundQuestionID = q.ID
) t
Note that string_agg() was added in SQL Server 2017.
In earlier versions, we can resort the for xml path solution:
select
q.*,
stuff(
(
', ' + tag_name tags
from questionTags qt
inner join tags t on t.TagID = qt.BoundTagID
where qt.BoundQuestionID = q.ID
order by tag_name
for xml path('')
),
1, 2, ''
) tags
from questions q
I have table ITEMS and column URL. All I need is in items.url to find similar rows:
Example of two similar rows:
ITEM_ID | URL
1 | www.google.com/test1/test2/test3.php
2 | www.yahoo.com/test1/test2/test3.php
3 | www.google.com/test5.php
4 | www.facebook.com/test5.php
As you can see the URL is similar JUST with different domains.
My query should be something like:
SELECT * FROM ITEMS
WHERE URL LIKE `%google.com%`...
AND `here code probably` ???
My query should return me ITEM_ID 2 and 4
You could group by the substring starting from the '/' character, and take the max ID in the group. Using postgresql syntax, it should look like this:
SELECT *
FROM ITEMS t
WHERE t.item_id IN (SELECT MAX(s.item_d)
FROM ITEMS s
GROUP BY SUBSTRING(s.url FROM POSITION('/' IN s.url)))
ORDER BY t.item_id;
Update: if you want only google domains, which have similar rows on different domains, you could use a filter EXISTS:
SELECT *
FROM ITEMS t
WHERE t.url LIKE 'www.google.com%'
AND EXISTS (SELECT 1
FROM ITEMS s
WHERE s.url NOT LIKE 'www.google.com%'
AND SUBSTRING(t.url FROM POSITION('/' IN t.url)) =
SUBSTRING(s.url FROM POSITION('/' IN s.url)));
My table structure is as follows :
id category
1 1&2&3
2 18&2&1
3 11
4 1&11
5 3&1
6 1
My Question: I need a sql query which generates the result set as follows when the user searched category is 1
id category
1 1&2&3
2 18&2&1
4 1&11
5 3&1
6 1
but i am getting all the results not the expected one
I have tried regexp and like operators but no success.
select * from mytable where category like '%1%'
select * from mytable where category regexp '([.]*)(1)(.*)'
I really dont know about regexp I just found it.
so please help me out.
For matching a list item separated by &, use:
SELECT * FROM mytable WHERE '&'||category||'&' LIKE '%&1&%';
this will match entire item (ie, only 1, not 11, ...), whether it is at list beginning, middle or end.
Let's say I have four tables: PAGE, USER, TAG, and PAGE-TAG:
Table | Fields
------------------------------------------
PAGE | ID, CONTENT
TAG | ID, NAME
USER | ID, NAME
PAGE-TAG | ID, PAGE-ID, TAG-ID, USER-ID
And let's say I have four pages:
PAGE#1 'Content page 1' tagged with tag#1 by user1, tagged with tag#1 by user2
PAGE#2 'Content page 2' tagged with tag#3 by user2, tagged by tag#1 by user2, tagged by tag#8 by user1
PAGE#3 'Content page 3' tagged with tag#7 by user#1
PAGE#4 'Content page 4' tagged with tag#1 by user1, tagged with tag#8 by user1
I expect my query to look something like this:
select page.content ?
from page, page-tag
where
page.id = page-tag.pag-id
and page-tag.tag-id in (1, 3, 8)
order by ? desc
I would like to get output like this:
Content page 2, 3
Content page 4, 2
Content page 1, 1
Quoting Neall
Your question is a bit confusing. Do you want to get the number of times each page has been tagged?
No
The number of times each page has gotten each tag?
No
The number of unique users that have tagged a page?
No
The number of unique users that have tagged each page with each tag?
No
I want to know how many of the passed tags appear in a particular page, not just if any of the tags appear.
SQL IN works like an boolean operator OR. If a page was tagged with any value within the IN Clause then it returns true. I would like to know how many of the values inside of the IN clause return true.
Below i show, the output i expect:
page 1 | in (1,2) -> 1
page 1 | in (1,2,3) -> 1
page 1 | in (1) -> 1
page 1 | in (1,3,8) -> 1
page 2 | in (1,2) -> 1
page 2 | in (1,2,3) -> 2
page 2 | in (1) -> 1
page 2 | in (1,3,8) -> 3
page 4 | in (1,2,3) -> 1
page 4 | in (1,2,3) -> 1
page 4 | in (1) -> 1
page 4 | in (1,3,8) -> 2
This will be the content of the page-tag table i mentioned before:
id page-id tag-id user-id
1 1 1 1
2 1 1 2
3 2 3 2
4 2 1 2
5 2 8 1
6 3 7 1
7 4 1 1
8 4 8 1
#Kristof does not exactly what i am searching for but thanks anyway.
#Daren If i execute you code i get the next error:
#1054 - Unknown column 'page-tag.tag-id' in 'having clause'
#Eduardo Molteni Your answer does not give the output in the question but:
Content page 2 8
Content page 4 8
content page 2 3
content page 1 1
content page 1 1
content page 2 1
cotnent page 4 1
#Keith I am using plain SQL not T-SQL and i am not familiar with T-SQL, so i do not know how your query translate to plain SQL.
Any more ideas?
This might work:
select page.content, count(page-tag.tag-id) as tagcount
from page inner join page-tag on page-tag.page-id = page.id
group by page.content
having page-tag.tag-id in (1, 3, 8)
OK, so the key difference between this and kristof's answer is that you only want a count of 1 to show against page 1, because it has been tagged only with one tag from the set (even though two separate users both tagged it).
I would suggest this:
SELECT page.ID, page.content, count(*) AS uniquetags
FROM
( SELECT DISTINCT page.content, page.ID, page-tag.tag-id
FROM page INNER JOIN page-tag ON page.ID=page-tag.page-ID
WHERE page-tag.tag-id IN (1, 3, 8)
)
GROUP BY page.ID
I don't have a SQL Server installation to check this, so apologies if there's a syntax mistake. But semantically I think this is what you need.
This may not give the output in descending order of number of tags, but try adding:
ORDER BY uniquetags DESC
at the end. My uncertainty is whether you can use ORDER BY outside of grouping in SQL Server. If not, then you may need to nest the whole thing in another SELECT.
In T-Sql:
select count(distinct name)
from page-tag
where tag-id in (1, 3, 8)
This will give you a count of the number of different tag names for your list of ids
Agree with Neall, bit confusing the question.
If you want the output listed in the question, the sql is as simple as:
select page.content, page-tag.tag-id
from page, page-tag
where page.id = page-tag.pag-id
and page-tag.tag-id in (1, 3, 8)
order by page-tag.tag-id desc
But if you want the tagcount, Daren answered your question
select
page.content,
count(pageTag.tagID) as tagCount
from
page
inner join pageTag on page.ID = pageTag.pageID
where
pageTag.tagID in (1, 3, 8)
group by
page.content
order by
tagCount desc
That gives you the number of tags per each page; ordered by the higher number of tags
I hope I understood your question correctly
Leigh Caldwell answer is correct, thanks man, but need to add an alias at least in MySQL. So the query will look like:
SELECT page.ID, page.content, count(*) AS uniquetags FROM
( SELECT DISTINCT page.content, page.ID, page-tag.tag-id FROM page INNER JOIN page-tag ON page.ID=page-tag.page-ID WHERE page-tag.tag-id IN (1, 3, 8) ) as page
GROUP BY page.ID
order by uniquetags desc