Progressive count using a query? - sql

I use this query to
SELECT userId, submDate, COUNT(submId) AS nSubms
FROM submissions
GROUP BY userId, submDate
ORDER BY userId, submDate
obtain the total number of submissions per user per date.
However I need to have the progressive count for every user so I can see how their submissions accumulate over time.
Is this possible to implement in a query ?
EDIT: The obtained table looks like this :
userId submDate nSubms
1 2-Feb 1
1 4-Feb 7
2 1-Jan 4
2 2-Jan 2
2 18-Jan 1
I want to produce this :
userId submDate nSubms progressive
1 2-Feb 1 1
1 4-Feb 7 8
2 1-Jan 4 4
2 2-Jan 2 6
2 18-Jan 1 7
EDIT 2 : Sorry for not mentioning it earlier, I am not allowed to use :
Stored procedure calls
Update/Delete/Insert/Create queries
Unions
DISTINCT keyword
as I am using a tool that doesn't allow those.

You can use a self-join to grab all the rows of the same table with a date before the current row:
SELECT s0.userId, s0.submDate, COUNT(s0.submId) AS nSubms, COUNT (s1.submId) AS progressive
FROM submissions AS s0
JOIN submissions AS s1 ON s1.userId=s0.userId AND s1.submDate<=s0.submDate
GROUP BY s0.userId, s0.submDate
ORDER BY s0.userId, s0.submDate
This is going to force the database to do a load of pointless work counting all the same rows again and again though. It would be better to just add up the nSubms as you go down in whatever script is calling the query, or in an SQL variable, if that's available in your environment.

The Best solution for this is to do it at the client.
It's the right tool for the job. Databases are not suited for this kind of task

Select S.userId, S.submDate, Count(*) As nSubms
, (Select Count(*)
From submissions As S1
Where S1.userid = S.userId
And S1.submDate <= S.submDate) As TotalSubms
From submissions As S
Group By S.userid, S.submDate
Order By S.userid, S.submDate

Related

How to get top 10 from one column and sort by another column in hive?

I want to find top 10 title with high number of user ids. So I used query like
select title,count(userid) as users from combined_moviedata group by title order by users desc limit 10
But i need to sort them based on title, I tried this query
select title,count(userid) as users from combined_moviedata group by title order by users desc,title asc limit 10
But it doesnot sort them. Merely returned same results. How to do this
The answer from #KaushikNayak is very close to what I'd consider the "right" answer.
At one level, work out what your top 10 records are
At a different level, sort them by a different field
The only thing I'd say is that if the 10th and 11th most common titles are tied for the same count, they should generally also be included in the results. This is a RANK().
WITH
ranked_titles AS
(
SELECT
RANK() OVER (ORDER BY COUNT(*) DESC) frequency_rank,
title
FROM
combined_moviedata
GROUP BY
title
)
SELECT
*
FROM
ranked_titles
WHERE
frequency_rank <= 10
ORDER BY
title
;
http://sqlfiddle.com/#!6/7283c/1
Note that in the example linked, 12 rows are returned. That is because 4 titles are all tied for the 9th most frequent, and it is actually impossible to determine which two should be selected in preference over the others. In this case selecting 10 rows would normally be statistically incorrect.
title frequency frequency_rank
title06 2 9
title07 2 9
title08 2 9
title09 2 9
title10 3 6
title11 3 6
title12 3 6
title13 4 4
title14 4 4
title15 5 2
title16 5 2
title17 6 1
You could make use of a WITH clause
with t AS
(
select title,count(userid) as users from combined_moviedata
group by title
order by users desc limit 10
)
select * FROM t ORDER BY title ;

Access "Not In" query not working while only In is working correctly

I have below given query which is working fine but I want to use "Not In" operator instead of "In" but its giving no results:
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) In (SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])))));
Desired Query:
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) Not In (SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])))));
Basically it is referencing a control on parent form and based on that in a subform I want to populate the priority numbers i.e 1,2,3 and if for that record 1 is entered I want to get only 2 and 3 as drop-down option.
ReocordID OrdID Brand Name Priority
2 1 Org 1 2
3 2 Org 2 1
4 1 Org 1 1
6 1 Org 1 3
7 3 Org 3 1
8 4 Org 1 1
9 5 Org 2 1
10 5 Org 2 2
11 6 Org 1 1
12 6 Org 2 2
If there is any other better approach for the same please suggest.
Thanks in advance for your help.
In all likelihood, your problem is that Priority can take on NULL values. In that case, NOT IN doesn't work as expected (although it does work technically). The usual advice is to always use NOT EXISTS with subqueries rather than NOT IN.
But, in your case, I would suggest conditional aggregation instead:
SELECT opd.Priority
FROM OrderProdDetails as opd
GROUP BY opd.Priority
HAVING SUM(IIF(opd.OrdID = [Forms]![UpdateOrder]![OdrID], 1, 0)) = 0;
The HAVING clause counts the number of times the forms OdrId is in the orders. The = 0 means it is never there. Plus, you no longer need a select distinct.
Thanks for your prompt answers however I figured out what the problem was and the answer to problem is.
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) Not In (SELECT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])
and ((OrderProdDetails.Priority) Is not null) ))));
I realized that the problem was happening only to those where there was a null value in priority so I puth the check of not null and it worked fine.
Thanks

Get MAX() on repeating IDs

This is how my query results look like currently. How can I get the MAX() value for each unique id ?
IE,
for 5267139 is 8.
for 5267145 is 4
5267136 5
5267137 8
5267137 2
5267139 8
5267139 5
5267139 3
5267141 4
5267141 3
5267145 4
5267145 3
5267146 1
5267147 2
5267152 3
5267153 3
5267155 8
SELECT DISTINCT st.ScoreID, st.ScoreTrackingTypeID
FROM ScoreTrackingType stt
LEFT JOIN ScoreTracking st
ON stt.ScoreTrackingTypeID = st.ScoreTrackingTypeID
ORDER BY st.ScoreID, st.ScoreTrackingTypeID DESC
GROUP BY will partition your table into separate blocks based on the column(s) you specify. You can then apply an aggregate function (MAX in this case) against each of the blocks -- this behavior applies by default with the below syntax:
SELECT First_column, MAX(Second_column) AS Max_second_column
FROM Table
GROUP BY First_column
EDIT: Based on the query above, it looks like you don't really need the ScoreTrackingType table at all, but leaving it in place, you could use:
SELECT st.ScoreID, MAX(st.ScoreTrackingTypeID) AS ScoreTrackingTypeID
FROM ScoreTrackingType stt
LEFT JOIN ScoreTracking st ON stt.ScoreTrackingTypeID = st.ScoreTrackingTypeID
GROUP BY st.ScoreID
ORDER BY st.ScoreID
The GROUP BY will obviate the need for DISTINCT, MAX will give you the value you are looking for, and the ORDER BY will still apply, but since there will only be a single ScoreTrackingTypeID value for each ScoreID you can pull it out of the ordering.

SQL Get n last unique entries by date

I have an access database that I'm well aware is quite poorly designed, unfortunately it is what I must use. It looks a little like the following:
(Row# is not a column in the database, it's just there to help me describe what I'm after)
Row# ID Date Misc
1 001 01/8/2013 A
2 001 01/8/2013 B
3 001 01/8/2013 C
4 002 02/8/2013 D
5 002 02/8/2013 A
6 003 04/8/2013 B
7 003 04/8/2013 D
8 003 04/8/2013 D
What I'm trying to do is obtain all information entered for the last n (by date) 'entries' where an 'entry' is all rows with a unique ID.
So if I want the last 1 entry I will get rows 6, 7 and 8. The last two entries will get me rows 4-8 etc.
I've tried to get the SN's needed in a subselect and then select all entries where those SN's appear, but I couldn't get it to work. Any help appreciated.
Thanks.
The proper Access syntax:
select *
from t
where ID in (select top 10 ID
from t
group by ID
order by max([date]) desc
)
I think this will work:
select *
from table
where Date in (
select distinct(Date) as unique_date from table order by unique_date DESC limit <num>
)
The idea is to use the subselect with a limit to only identify dates you care about.
EDIT: Some databases do not allow a limit in a subquery (I'm looking at you, mysql). In that case, you'll have to make a temporary table out of the subquery then select * from it.

Error when COUNT after MAX?

I have a table Act in a medical database :
IDAct Historic IDPatient
1 2001-01-01 1
1 2001-01-02 1
2 2001-01-01 2
3 2001-01-03 1
I would like to compute the column IDActPerPatient:
IDAct Historic IDPatient IDActPerPatient
1 2001-01-02 1 1
2 2001-01-01 2 1
3 2001-01-03 1 2
The Act table contains Acts with the historic of every modification of an act. (the index is the pair (IDAct,Historic)).
So I'm interested in the last modified acts:
SELECT A.IDActe, MAX(Historic) AS Historic FROM Act A GROUP BY IDAct
Now, I'd like to number the Acts per patient. So I count the number of acts with an IDAct less or equal for one patient.
I have created a view LastAct with the previous request and I try this one :
SELECT DA1.*, COUNT(*) AS IDActPerPatient
FROM LastAct DA1
INNER JOIN LastAct DA2 ON DA1.IDPatient = DA2.IDPatient
AND DA2.IDActe >= DA1.IDAct
GROUP BY DA1.IDAct
...which does not work!
I get large numbers in IDActPerPatient when an act has several version in historic (for a patient who has 1 act in 3 versions I have 81).
Do you have an idea where the problem comes from ?
SELECT A.IDActe,
MAX(Historic) AS Historic,
(SELECT COUNT(DISTINCT IDAct) FROM ACT B WHERE A.IDPatient=B.IDPatient)
FROM Act A
GROUP BY IDAct
?
Thank you! I don't use select in the select enough but It's really helpful here!
here is the fixed request:
SELECT A.IDAct, A.IDPatient,
MAX(Historic) AS Historic,
(SELECT COUNT(DISTINCT IDAct) FROM Act B WHERE A.IDPatient=B.IDPatient
AND A.IDAct>=B.IDAct) AS IDActPerPatient
FROM Act A
GROUP BY IDAct