sql count all items that day until start of database isn't working because of time - sql

I am trying to count each item in a database table, that is deployments. I have counted the total number of items 3879, by doing this:
use Bamboo_Version6
go
SELECT Count(STARTED_DATE)
FROM [Bamboo_Version6].[dbo].[DEPLOYMENT_RESULT]
But I have been struggling to get the number of items each day until the start. I have tried using some of the other similar answers to this like:
select STARTED_Date, count(deploymentID)
from [Bamboo_Version6].[dbo].[DEPLOYMENT_RESULT]
WHERE STARTED_Date>=dateadd(day,datediff(day,0,STARTED_Date)- 7,0)
GROUP BY STARTED_Date
But this will return every id, and a 1 beside it because the dates have times which are making it unique, so I tried doing this: CONVERT(varchar(12),STARTED_DATE,110) to try and fix the problem but it still happens. How can I count this without, getting all the id's or every id as 1 each time?

Remove the time component:
select cast(STARTED_Date as date) as dte, count(deploymentID)
from [Bamboo_Version6].[dbo].[DEPLOYMENT_RESULT]
group by cast(STARTED_Date as date)
order by dte;
I'm not sure what the WHERE clause is supposed to be doing, so I just removed it. If it is useful, add it back in.

I have another efficient way of doing this, may be try this with an over clause
SELECT cast(STARTED_DATE AS DATE) AS Deployment_date,
COUNT(deploymentID) OVER ( PARTITION BY cast(STARTED_DATE AS DATE) ORDER BY STARTED_DATE) AS NumberofDeployments
FROM [Bamboo_Version6].[dbo].[DEPLOYMENT_RESULT]

Related

SQL filtering activity after certain event

I am struggling with a SQL query.
My query looks something like this:
Select
Count(user-id),
sum(distinct(date),
Sum(characters-posted)
From (
Select
Date,
User-Id,
Session-Id,
Characters—posted,
Variant-id
From database-name
Where date between ‘2022-09-01’ and ‘2022-09-31’)
This works ok. But, there is another field in the table “mailing-list”, which is just 0 or 1. I want to only get activity for members from the date when they join the mailing list onwards, even if they then leave the list, so can’t just do “where mailing-list=1”.
How can I do this?
It's not obvious what works fine for you as it seems to be uncommon to sum dates, given it is a regular date format. Are you trying to get number of active dates? as for the bottom question you might.
As for your buttom line quesiton, it seems that you might want to use a cte or subselect in a join.
your query...
from db_name dbn
inner join (select user_id, min(date) date from database_name
where mailing_list = 1 group by 1) start_date
on start_date.user_id = dbn.user_id
and start_date.date <= dbn.date
That way you're only getting activity starting from the first time your users join the mailing list.
But I still think you have an error in your final query, check it out.

Count events between dates, but dates are rolling based on a variable "first event"

I have been lurking around and learning a bit of SQL recently so apologies if this is something easy I am entirely misunderstanding.
I am attempting to find out how many "things" different users did in their first 90 days since their first ever event, think like taxi trips or card transactions in the first 90 days. I'm working in BigQuery.
So, I have something that looks like this:
transaction_id
customer_id
transaction_date
67495549
49543345
03/07/2014
71849572
6321113
08/12/2016
75847266
94429299
01/03/2017
75903310
49543345
01/03/2017
82990678
10843
06/09/2017
85785566
384900
10/10/2017
88019966
7444632
21/11/2017
And the way I'm currently thinking about is is the following:
SELECT
DISTINCT customer_id,
MIN(transaction_date) AS First_transaction,
MIN(transaction_date)+89 AS Last_useful_transaction_date,
COUNT(transaction_id)
FROM
Transactions
/* WHERE
transaction_date BETWEEN MIN(transaction_date) AND MIN(transaction_date)+89 */
GROUP BY
customer_id
Now, without the commented-out part, the output looks like I want it to: one customer ID per row, and the count of how many transactions there were. I have added the first and "last useful" dates for reference. Of course, the count of events is an overall count, and not within the first 90 days, but it looks like it should.
Where I'm stuck is that part (here commented out) where I only count the rows where a date is between the first transaction date and the first transaction + 89 days date. I get errors with BETWEEN and MIN not working nicely together ("Aggregate function MIN not allowed in WHERE clause at [11:28]").
So this is where I'm currently stuck at. I also have the feeling that when I fix this part then maybe I could have an issue with the MIN date value being considered absolute rather than "MIN for that user"? I'm still struggling with nested queries but I believe a solution might be somewhere down that hole, right?
Does it even make sense?
Try this one:
select
customer_id,
MIN(transaction_date) AS First_transaction,
COUNT(transaction_id)
from (
select *
from transactions
where true
qualify transaction_date <= min(transaction_date) over (partition by customer_id) + 89
)
group by customer_id

Add previous load count using the the present count and the timestamp column

I have a table with the following columns
id, timestamp, current load count, previous load count
and it has many rows. I have values for all the first three columns, but for the "previous load count", I need to get the count of the date one day before the count of the current load count.
See the below image (table example) to view the sample table
For example: previous load count of id:4 is the count same as the current load count of id:5.
Is there anyway to write a SQL statement to update the previous load count?
Can you try this?
SELECT [id]
,[timestamp]
,[current load count]
,LAG([current load count]) OVER (ORDER BY [timestamp] ASC, [id]) AS [previous load count]
FROM [table]
The LAG function can be used to access data from a previous row in the same result set without the use of a self-join.
It is available after SQL Server 2012.
In the example I added ordering by id, too - in case you have records with same date, but you can remove it if you like.
If you need exactly one day before, consider a join:
select t.*, tprev.load_count as prev_load_count
from t left join
t tprev
on tprev.timestamp = dateadd(day, -1, t.timestamp);
(Note: If the timestamp has a time component, you will need to convert to a date.)
lag() gives you the data from the previous row. If you know you have no gaps, then these are equivalent. However, if there are gaps, then this returns NULL on the days after the gap. That appears to be what you are asking for.
You can incorporate either this or lag() into an update:
update t
set prev_load_count = tprev.load_count
from t join
t tprev
on tprev.timestamp = dateadd(day, -1, t.timestamp);

Why are different result between use date_part and exactly date parameter query data in peroid date?

I'm try to count distinct value in some columns in a table.
i have a logic and i try to write in 2 way
But i get diffent results from this two query.
Can any one help to clarify me? I dont know what wrong is code or i think.
SQL
select count(distinct membership_id) from members_membership m
where date_part(year,m.membership_expires)>=2019
and date_part(month,m.membership_expires)>=7
and date_part(day,m.membership_expires)>=1
and date_part(year,m.membership_creationdate)<=2019
and date_part(month,m.membership_creationdate)<=7
and date_part(day,m.membership_creationdate)<=1
;
select count(distinct membership_id) from members_membership m
where m.membership_expires>='2019-07-01'
and m.membership_creationdate<='2019-07-01'
;
I actually think that this is the query you intend to run:
SELECT
COUNT(DISTINCT membership_id)
FROM members_membership m
WHERE
m.membership_expires >= '2019-07-01' AND
m.membership_creationdate < '2019-07-01';
It doesn't make sense for a membership to expire at the same moment it gets created, so if it expires on midnight of 1st-July 2019, then it should have been created strictly before that point in time.
That being said, the problem with the first query is that, e.g., the restriction on the month being on or before July would apply to every year, not just 2019. It is difficult to write a date inequality using the year, month, and day terms separately. For this reason, the second version you used is preferable. It is also sargable, meaning that an index on membership_expires or membership_creationdate can be used.
There is an issue with the first query:
select count(distinct membership_id) from members_membership m
where date_part(year,m.membership_expires)>=2019
and date_part(month,m.membership_expires)>=7
and date_part(day,m.membership_expires)>=1
and date_part(year,m.membership_creationdate)<=2019
and date_part(month,m.membership_creationdate)<=7
and date_part(day,m.membership_creationdate)<=1; -- do you think that any day is less than 1??
-- this condition will be satisfy by only 01-Jul-2019, But I think you need all the dates before 01-Jul-2019
and date_part(day,m.membership_creationdate)<=1 is culprit of the issue.
even membership_creationdate = 15-jan-1901 will not satisfy above condition.
You need to always use date functions on date columns to avoid such type of issue. (Your second query is perfectly fine)
Cheers!!
The reason could be due to a time component.
The proper comparison for the first query is:
select count(distinct membership_id)
from members_membership m
where m.membership_expires >= '2019-07-01' and
m.membership_creationdate < '2019-07-02'
--------------------------------^ not <= ---^ next day
This logic should work regardless of whether or not the "date" has a time component.

SQL- get dates that were used in the WHERE clause?

We have a ERP that integrates nicely with Crystal Reports.
Now, we can add filters through this application, and it passes these to the report (not as parameters but somehow adds this to the WHERE clause).
The problem is, when filtering dates, we have no way in the report to determine what date range the user selected (as we want to show this date on the report).
Any idea how I can show this through SQL?
I was thinking of using the dual table, and selecting a huge list of dates, then using the MIN and MAX of these dates to determine which was selected. The problem is, I can't join this onto my original query without adding LOTS of rows.
I have this so far:
SELECT
MIN(DTE) MIN_DTE,
MAX(DTE) MAX_DTE
FROM
(
SELECT
TRUNC(SYSDATE)-(5*365) + ROWNUM AS DTE
FROM
DUAL
CONNECT BY
ROWNUM <= (10*365)
)
WHERE
DTE >= '12-NOV-07'
AND DTE <= '12-DEC-07'
But the problem is I can't work out how to join that to my original query without upsetting the row cont.
Any other ideas?
That query returns only one row, so it won't upset the row count at all, unless there is something else going on (like, maybe, the automatic filtering doesn't work in subqueries).
Otherwise, this should work as expected:
SELECT q.*, max_min.*
FROM ( ... put your original query here ...) q,
( ... put the subquery that returns one row with max & min here ...) max_min
That's all to it.