Select count from another table - mysql

I have two tables: ToDoList & ToDotasks
I need to write a query that will return me the column ot ToDoList as well as a count of incomplete tasks i.e. where taskstatus=0 for the ToDotasks table
My query:
SELECT *,(select count(*) from todotasks where taskstatus = 0 group by
listid) as TotalIncomplete FROM dbo.ToDoList
Error: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
ToDoList:
ListID ListName
1 List 5600
2 List 22
3 List 30
4 List 4
5 List 1
ToDotasks
taskid ListID taskStatus
3 2 0
6 3 0
14 3 0
16 3 0
19 4 1
36 1 0
38 1 1
39 1 0
40 2 0
41 2 0
What I am after:
ListID ListName TotalIncomplete
1 List 5600 2
2 List 22 3
3 List 30 3
4 List 4 0
5 List 1 0

Please try the following...
SELECT ToDoList.ListID AS ListID,
ToDoList.ListName AS ListName,
COUNT( incompleteTasks.ListID ) AS IncompleteTaskCount
FROM ToDoList
LEFT JOIN
(
SELECT ListID AS ListID
FROM ToDoTasks
WHERE taskStatus = 0
) incompleteTasks ON ToDoList.ListID = incompleteTasks.ListID
GROUP BY ToDoList.ListID
ORDER BY ToDoList.ListID;
The logic I used was...
To get a count of incomplete tasks we would first need a list of those tasks that have a taskStatus of 0. The taskid will be irrelevant to the count and once tested so will taskStatus be irrelevant. Therefore this list only needs to include each qualifying task's ListID. I have given this list the name incompleteTasks.
ToDoList LEFT JOIN incompleteTasks will give us a table consisting of each value from incompleteTasks with its corresponding values from ToDoList. Where a record from ToDoList does not have any corresponding records in incompleteTasks we get the values from ToDoList accompanied by a NULL value.
By grouping the LEFT JOINed list on its value of ListID from List we achieve a grouping that corresponds with our desired output. We then use COUNT() to count the number of times that ListID appears in our joined list's field from incompleteTasks. Note : COUNT() does not count NULL values.
The list resulting from the above can then be sorted by the value of ListID from List using ORDER BY ToDoList.ListID.
If you have any questions or comments, then please feel free to post a Comment accordingly.

Its pretty straight forward.. Here is the solution
select ToDoList.lisid, ToDoList.lastname, count(ToDoTasks.taskstatus) from
ToDoList JOIN ToDoTasks ON ToDoList.listid = ToDoTasks.listid
where ToDoTasks.taskstatus = 0
group by ToDoList.listname,ToDoList.listid
Updated Query with your table names....
Hope this helps. Cheers !!!

Related

Sql select where a column has been set atleast once

I have this table
**applications**
id user_id company_id shortlisted
1 10 99 0
2 10 100 1
3 10 101 1
4 10 102 0
5 11 99 1
6 12 99 0
6 12 101 0
What I want is to select all users
which have been shortlisted at-least once
which have not been shortlisted at all
For the first case, i have the following query:
SELECT user_id
from applications
where shortlisted=1
Group
By user_id
and this gives me the expected result like below
**applications**
user_id
10
11
But I'm trying the following query for the second case and it returns me an empty set:
Select user_id
from applications as Application
where shortlisted=0
and NOT EXISTS(Select user_id from applications where user_id=Application.user_id and shortlisted=1)
What am i missing?
PS: Please ignore any typos as i typed them manually for this post.
To get both results in a single query simply use aggregation:
select user_id, max(shortlisted) as was_shortlisted
from applications
group By user_id
You can use group by and having for both.
For the first:
select user_id
from applications
group By user_id
having max(shortlisted) = 1;
For the second:
select user_id
from applications
group By user_id
having max(shortlisted) = 0;
In all honesty, your version with the where is more efficient for the first query. This is just to show how closely related the queries are.
You can try following query;
select user_id from table1
group by user_id having MIN(shortlisted) = 1
This will give you to at least have shortlisted = 1 condition and don't have shortlisted = 0 records.

Find distinct elements that match multiple values from the same column

Lets say this is the table I am talking about
id pId fId
1 1 1
2 2 1
3 2 2
4 3 2
I need to get a list of pId's who have a match to ALL of the given indices in a list of fId's.
What I mean is ->
Consider the list of fId's to be:
(1,2)
Then the result should be
2
Because only pId 2 has a match to all given entries in the list of fId's (which would be 1 and 2).
I couldn't find any way to do it so far - any help is highly appreciated :-)
Aggregate on pid column and use a having clause.
select pid
from tablename
group by pid
having sum(case when fid in (1,2) then 1 else 0 end) >= 2

Correlated Subqueries - Counting records "less than" the main query record

I am attempting to determine which "iteration" any given record is by counting the number of records that preceded it and have certain matching characteristics. Essentially, I'd like to know the number of records with the same parent record & category that also have an ID# less than [my record's ID#]. I can get a correlated subquery to count the number of records with the same parent and category, but when I try to add an ID filter, my subquery filter can't find the column "T1.ID" - the ID# field from my main table.
My SQL follows, the asterisks are where I've tried and failed to limit results based on "T1's" record ID (I obviously exclude the asterisks in my actual SQL)
select T1.ID, T2.ITERATION
from TICKET as T1
inner join
(select COUNT(T3.ID) as ITERATION, T3.CATEGORY_ID, T3.PARENT_ID
from TICKET as T3
where T3.IS_PARENT = 0 **AND T3.ID < T1.ID**
group by T3.PARENT_ID, T3. CATEGORY_ID)
as T2 on (T1.PARENT_ID = T2.PARENT_ID AND
T1. CATEGORY_ID = T2.CATEGORY_ID)
where T1.IS_PARENT = 0
I other programs, I've used functions that build a subquery to accomplish a similar result, so if I should be looking in that direction instead, I'd appreciate that feedback.
I'm counting from the same table, so sample data:
ID PARENT_ID CATEGORY
10 1 A
11 2 A
12 1 B
13 3 A
14 2 A
15 1 A
16 3 B
17 1 A
And desired output:
ID ITERATION (explanation)
10 0 (No preceding ID with same parent & category)
11 0 (No preceding ID with same parent & category)
12 0 (No preceding ID with same parent & category)
13 0 (No preceding ID with same parent & category)
14 1 (ID 11 precedes 14 and shares parent & category)
15 1 (ID 10 precedes 15 and shares parent & category)
16 0 (No preceding ID with same parent & category)
17 2 (ID's 10, 15 precede 17 and share parent & category)
I think this is what you want:
SELECT
ID,
PARENT_ID,
CATEGORY,
(SELECT COUNT(*) FROM TICKET
WHERE ID < T.ID
AND CATEGORY = T.CATEGORY
AND PARENT_ID = T.PARENT_ID
) AS ITERATION
FROM TICKET T
ORDER BY ID
Result using your sample data:
ID PARENT_ID CATEGORY ITERATION
10 1 A 0
11 2 A 0
12 1 B 0
13 3 A 0
14 2 A 1
15 1 A 1
16 3 B 0
17 1 A 2

Access Totals Query Not Necessarily Returning First Record

I have a table of data like this:
id user_id A B C
=====================
1 15 1 2 3
2 15 1 2 5
3 20 1 3 9
4 20 1 3 7
I need to remove duplicate user ids and keep the record that sorts lowest when sorting by A then B then C. So using the above table, I set up a temp query (qry_temp) that simply does the sort--first on user_id, then on A, then on B, then on C. It returns the following:
id user_id A B C
====================
1 15 1 2 3
2 15 1 2 5
4 20 1 3 7
3 20 1 3 9
Then I wrote a Totals Query based on qry_temp that just had user_id (Group By) and then id (First), and I assumed this would return the following:
user_id id
===========
15 1
20 4
But it doesn't seem to do that--instead it appears to be just returning the lowest id in a group of duplicate user ids (so I get 1 and 3 instead of 1 and 4). Shouldn't the Totals query use the order of the query it's based upon? Is there a property setting in the query that might impact this or another way to get what I need? If it helps, here is the SQL:
SELECT qry_temp.user_id, First(qry_temp.ID) AS FirstOfID
FROM qry_temp
GROUP BY qry_temp.user_id;
You need a different type of query, for example:
SELECT tmp.id,
tmp.user_id,
tmp.a,
tmp.b,
tmp.c
FROM tmp
WHERE (( ( tmp.id ) IN (SELECT TOP 1 id
FROM tmp t
WHERE t.user_id = tmp.user_id
ORDER BY t.a,
t.b,
t.c,
t.id) ));
Where tmp is the name of your table. First, Last, Min and Max are not dependent on a sort order. In relational databases, sort orders are quite ephemeral.

MySQL Sum grouping issue

I have a table containing jobs to be invoiced. Each row contains two columns, 'value' and 'group'. Like this
ID Value Group
1 2000.00 1
2 2000.00 1
3 1000.00 0
4 1000.00 0
What I need to do is combine the values in Rows 1 and 2 (because they have the same group number), then return rows 3 and 4 as normal (so, not grouped together):
4000 //Rows 1 and 2 combined
1000 //Row 3 returned as whole value
1000 //Row 4 returned as whole value
I've tried to use GROUP BY in the query, so something like
SELECT SUM(Value) AS totalValue FROM table GROUP BY Group
However this returns
4000
2000 //Row 3 and 4 combined
It's combining Row 3 and 4 because they share the same Group number, its grouping them together.
My problem is, I don't want them grouped together. I want them to return separately as they have a value of zero. Is there any way for me to do this?
SELECT Group AS Unique_ID, SUM(Value) AS totalValue FROM table WHERE Group>0 GROUP BY Group
UNION
SELECT id AS Unique_ID, Value As totalValue FROM table WHERE Group=0