Count associations in sqlite database query? - sql

I have a sqlite database with three tables: Notes, Lists, and Notes-in-Lists.
Both Notes and Lists have an autogenerated id column and some extra data columns like title. Notes-in-Lists is an association table with an autokey, and two foreign keys that point to a Note id and a List id.
I have a query that returns all notes in a given list:
Select _id, title From Notes
Join Notes_in_Lists On Notes._id=Notes_in_Lists.note_id
Where Notes_in_Lists.list_id=2
This would return all note titles and ids from List 2 for example.
However, notes can be in multiple lists and I need to be able to tell if a note is associated with multiple lists. This is indicated by the same Notes_in_Lists.note_id being listed multiple times in the Notes_in_Lists table.
Easy enough to do by itself:
Select Count(note_id) From Notes_in_Lists Where note_id=2
But I need to combine the two queries above into one query and I have not idea where to begin.
Edit
Sample data
Notes:
_id title
1 "Note 1"
2 "Note 2"
3 "Note 3"
4 "Note 4"
Note_in_Lists
_id note_id list_id
1 1 2
2 1 3
3 2 2
4 3 1
5 4 2
6 4 4
7 4 5
Sample output (query for contents of list 2):
_id title numberOfLists
1 "Note 1" 2
2 "Note 2" 1
4 "Note 4" 3

Select Notes._id, Notes.title, Count(Nil2.list_id)
From Notes
Inner Join Notes_in_Lists NiL1 On Notes._id=NiL1.note_id
Inner Join Notes_in_Lists NiL2 On Notes._id=NiL2.note_id
Where NiL1.list_id=2
Group By Notes._id, Notes.title;
It can seem wasteful to do two joins, but that's what you need to basically run two queries.

SELECT n._ID, Title, Count(*) numberOfLists
FROM Notes n, Notes_In_Lists l
where n._id = l.note_id
AND NOT EXISTS (Select 1
from notes_in_lists l2 where
l2.note_Id = n._id
AND l._Id = 2)
group by n._ID, n.Title

Related

Return count id's value from multiple rows in one column Postgres

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

How can I show combined "article" which has the same amount of "bids"?

I want to show the combinations of "offers" that have the same number of "bids". The Both "OID" of the combination and the number of "bids" should be output.
I know the logic I want to show which article has the same bids in combination of other article, but I don't know how I can write it down. Some code can help me to understand this.
More information about the structure of the tables "offer" and "bid". Also a "Expected result" which is shown the result
I really want to learn SQL.
Try running this..
SELECT temp1.OID as OID1,temp2.OID as OID2,temp1.count1 as numberOfBids
FROM
(SELECT t1.OID,COUNT(t1.BID) as count1
FROM bid t1 group by t1.OID) temp1
JOIN
(SELECT t2.OID,COUNT(t2.BID) as count2
FROM bid t2 group by t2.OID) temp2
ON temp1.count1= temp2.count2
AND temp1.OID <> temp2.OID
But it will give output as below table
OID1 OID2 numberOfBids
1 2 2
1 5 2
2 5 2
5 1 2
5 2 2

Find 'Most Similar' Items in Table by Foreign Key

I have a child table with a number of charact/value pairs for a given 'material' (MaterialID). Any material can have a number of charact values and may have several of the same name (see id's 2,3).
The table has a large number of records (8+ million). What I'm trying to do is find the materials that are the most similar to a supplied material. That is, when I supply a MaterialID, I would like an ordered list of the most similar other materials (those with the most matching charact/value pairs).
I've done some research but, I may be missing some key terms or just not conceptualizing the problem correctly.
Any hints as to how to go about this would be very much appreciated.
ID MaterialID Charact Value
1 1 ROT_DIR CCW
2 1 SPECIAL_FEATURE CATALOG_CP
3 1 SPECIAL_FEATURE CHROME
4 1 SCHEDULE 80
5 2 BEARING_TYPE SB
6 2 SCHEDULE 80
7 3 ROT_DIR CCW
8 3 SPECIAL_FEATURE CATALOG_HSB
9 3 BEARING_TYPE SP
10 4 NDE_STYLE W_FAN
11 4 BEARING_TYPE SB
12 4 ROT_DIR CW*
You can do this with a self join:
select t.materialid, count(*) as nummatches
from t join
t tmat
on t.Charact = tmat.Charact and t.value = tmat.value
where tmat.materialid = #MaterialId
group by t.materialid
order by nummatches desc;
Notes:
You might want to remove the specified material, by adding where t.MaterialId <> tmat.MaterialId to the where clause.
If you want all materials, then make the join a left join and move the where condition to the on clause.
If you want only one material with the most matches, use select top 1.
If you want all materials with the most matches when there are ties, use `select top (1) with ties.

How to join these tables with conditional joins

I saw some useful tips in the web, however I still have some questions.
This is the "main" part of the new site we are creating, it is based on SQL SERVER 2012, the "TAREAS" table is the main key table, which has a self join. I found a way to search for the "tree" of the table, TAREA=TASK, Spanish to English, so basically it is a task manager, on which one task could be part of a primary task, or be a secondary task which can have more "child" tasks. I did it using Common table expressions.
the thing here is on the ID_TipoTarea (TaskType) on TAREAS table, can be on one specific type of task, for example on the diagram there are 2 types availables (but there are and will be more), TipoTareaDesarrollo or TipoTareaEventoSalon, the ID_TipoTarea cant be on both tables, so if ID_TipoTarea=1 then I join on TIpoTareaDesarrollo, if ID_TipoTarea=2 then I join on TipoTareaEventoSalon and so on ID_TipoTarea=3 to another table, and there will be more types, can you help me out?.
how can it be achieved using this query (this is the query to get all the levels on the main table, but I need the conditional joins).
with tareasCTE (id_tarea,id_tareaorigen,id_tipoTarea,nivel)
as(
select *,0 as nivel from tareas t
where id_tarea=#ID_Tarea
union all
select t2.*,nivel+1 from tareasCTE t
inner join tareas t2
on t.id_tarea=t2.id_tareaOrigen
)
I get this output
ID_Tarea, ID_TareaORigen, Nivel, ID_TipoTarea
3 NULL 0 null (no join)
4 3 1 1 (join this one with TipoTareaDesarrollo)
5 3 1 1 (join this one with TipoTareaDesarrollo)
6 3 1 3 (join this one with AnotherTable)
7 4 2 2 (join this one with TipoTareaEventoSalon)
8 4 2 2 (join this one with TipoTareaEventoSalon)
9 4 2 4 (join this one with AnotherTable2)
10 9 3 1 (join this one with TipoTareaDesarrollo)
11 9 3 1 (join this one with TipoTareaDesarrollo)
12 9 3 null (no Join)
13 12 4 1 (join this one with TipoTareaDesarrollo)
14 12 4 2 (join this one with TipoTareaEventoSalon)
15 12 4 2 (join this one with TipoTareaEventoSalon)
You can combine tables TipoTareaDesarrollo, TipoTareaEventoSalon, AnotherTable, AnotherTable2 into a single table using the UNION clause and package this in a second CTE as such:
WITH TipoAreasCTE as
(
SELECT * FROM TipoTareaDesarrollo
UNION
SELECT * FROM TipoTareaEventoSalon
UNION
SELECT * FROM AnotherTable
UNION
SELECT * FROM AnotherTable2
)
You can then join tareasCTE to TipoAreasCTE.
Note that the different tables in the UNION must have the same number of columns with the same datatypes; if not you must use a SELECT list and perhaps CAST the datatypes to make them similar.

Why does this query return "incorrect" results?

I have 3 tables:
'CouponType' table:
AutoID Code Name
1 CouT001 SunCoupon
2 CouT002 GdFriCoupon
3 CouT003 1for1Coupon
'CouponIssued' table:
AutoID CouponNo CouponType_AutoID
1 Co001 1
2 Co002 1
3 Co003 1
4 Co004 2
5 Co005 2
6 Co006 2
'CouponUsed' table:
AutoID Coupon_AutoID
1 2
2 3
3 5
I am trying to join 3 tables together using this query below but apparently I am not getting right values for CouponIssued column:
select CouponType.AutoID, Code, Name, Count(CouponIssued.CouponType_AutoID), count(CouponUsed.Coupon_AutoID)
from (CouponType left join CouponIssued
on (CouponType.AutoID = CouponIssued.CouponType_AutoID))
left join CouponUsed
on (couponUsed.Coupon_AutoID = CouponIssued.AutoID)
group by CouponType.AutoID, code, name
order by code
The expected result should be like:
**Auto ID Code Name Issued used**
1 CouT001 SunCoupon 3 2
2 CouT002 GdFriCoupon 3 1
3 CouT003 1for1Coupon 0 0
Thanks!
SELECT t.AutoID
,t.Code
,t.Name
,count(i.CouponType_AutoID) AS issued
,count(u.Coupon_AutoID) AS used
FROM CouponType t
LEFT JOIN CouponIssued i ON i.CouponType_AutoID = t.AutoID
LEFT JOIN CouponUsed u ON u.Coupon_AutoID = i.AutoID
GROUP BY 1,2,3;
You might consider using less confusing names for your table columns. I have made very good experiences with using the same name for the same data across tables (as far as sensible).
In your example, AutoID is used for three different columns, two of which appear a second time in another table under a different name. This would still make sense if Coupon_AutoID was named CouponIssued_AutoID instead.
change count(Coupon.CouponType_AutoID) to count(CouponIssued.CouponType_AutoID) and count(Coupon.Coupon_AutoID) to count(CouponUsed.Coupon_AutoID)