Value of first day of current month (except zero) - date

I need a way to get the value on column B that corresponds to the 1st day of the present month like so:
Table A
+---------------------+------+
| ColA | ColB |
+---------------------+------+
| 28/10/2012 00:19:01 | 42 |
| 29/10/2012 00:29:01 | 100 |
| 30/10/2012 00:39:01 | 23 |
| 31/10/2012 00:29:01 | 1 |
| 1/11/2012 00:19:01 | 24 |<---
| 2/11/2012 00:19:01 | 4 |
| 3/11/2012 00:19:01 | 2 |
+---------------------+------+
Table B
+---------------------+------+
| ColA | ColB |
+---------------------+------+
| 28/11/2012 00:19:01 | 67 |
| 29/11/2012 00:29:01 | 2 |
| 30/11/2012 00:39:01 | 63 |
| 31/11/2012 00:29:01 | 5 |
| 1/12/2012 00:19:01 | 69 |<---
| 2/12/2012 00:19:01 | 42 |
| 3/12/2012 00:19:01 | 6 |
+---------------------+------+
Table C
+---------------------+------+
| ColA | ColB |
+---------------------+------+
| 28/11/2012 00:19:01 | 11 |
| 29/11/2012 00:29:01 | 12 |
| 30/11/2012 00:39:01 | 3 |
| 31/11/2012 00:29:01 | 20 |
| 1/12/2012 00:19:01 | 0 |
| 2/12/2012 00:19:01 | 71 |<---
| 3/12/2012 00:19:01 | 21 |
+---------------------+------+
So I need to be able to have a formula that I can use in a cell anywhere on my sheet that gets me that "24" in Table A. In other words, it would always get me the value corresponding to the first day of the current month.
Then when the month is over and the next month starts, the same formula will get me the value on column B corresponding to the 1st day of the present month again, in Table B that would be "69".
Now one thing I'd like to add is, if the value on column B corresponding to the 1st day of the month is equal to "0" then the formula will search for the next cell/day until if finds a value greater than "0", and it outputs that one. See Table C. In this example it would be "71".
Is this possible? I imagine so I just can't figure out how to go about doing it.
Dummy file:
https://docs.google.com/spreadsheets/d/1ExXtmQ8nyuV1o_UtabVJ-TifIbORItFMWjtN6ZlruWc/edit?usp=sharing

if your timestamps are sorted like in your example try:
=--FILTER(B:B, B:B>0, MONTH(A:A)=MONTH(TODAY()))

You can use MINIFS to get the first date of this month that has a corresponding value > 0:
=MINIFS(A1:A7,B1:B7,">0",A1:A7,">"&EOMONTH(TODAY(),-1),A1:A7,"<="&EOMONTH(TODAY(),0))
You can then combine that formula with a basic INDEX/MATCH to get the correct value:
=INDEX(B1:B7,MATCH(MINIFS(A1:A7,B1:B7,">0",A1:A7,">"&EOMONTH(TODAY(),-1),A1:A7,"<="&EOMONTH(TODAY(),0)),A1:A7,0))

Related

postgreSQL question: get data by last date of each record and subtract from last date number of days

Please help me make a request. i'm at a dead end.
There are 2 tables:
“Trains”:
+----+---------+
| id | numbers |
+----+---------+
| 1 | 101 |
| 2 | 102 |
| 3 | 103 |
| 4 | 104 |
| 5 | 105 |
+----+---------+
“Passages”:
+----+--------------+-------+---------------------+
| id | train_number | speed | date_time |
+----+--------------+-------+---------------------+
| 1 | 101 | 26 | 2021-11-10 16:26:30 |
| 2 | 101 | 28 | 2021-11-12 16:26:30 |
| 3 | 102 | 24 | 2021-11-14 16:26:30 |
| 4 | 103 | 27 | 2021-11-15 16:26:30 |
| 5 | 101 | 29 | 2021-11-16 16:26:30 |
+----+--------------+-------+---------------------+
The goal is to go through the train numbers from the Trains table, take from the existing ones from the Passages table by the latest date (date_time) and the number of passages for “the last date for each train” - N days. as I understand date_time - interval "N days". should get something like:
+----+--------+---------------------+----------------+
| id | train | last_passage | count_passages |
+----+--------+---------------------+----------------+
| 1 | 101 | 2021-11-10 16:26:30 | 2 |
| 2 | 102 | 2021-11-14 16:26:30 | 1 |
| 3 | 103 | 2021-11-15 16:26:30 | 1 |
| 4 | 104 | null | 0 |
| 5 | 105 | null | 0 |
+----+--------+---------------------+----------------+
ps: "count_passages" - for example, last passage date minus 4 days
I tried through "where in" but I can’t create the necessary and correct request

How to display results for each year dynamic column in Crystal report

How to display each years cost in dynamic column (Max 3 years) in Crystal report.
Parameters : Date From and Date To
Crystal report Version : 2013
Table : Jobs
+-------+------------+------------+
| EQ_no | Job_Date | Total_Cost |
+-------+------------+------------+
| 1006 | 01/30/2017 | 250 |
| 1006 | 01/31/2018 | 350 |
| 1006 | 01/01/2019 | 150 |
| 1006 | 02/01/2019 | 322 |
| 1006 | 05/05/2019 | 450 |
| 1006 | 02/02/2020 | 500 |
| 1006 | 02/03/2021 | 1212 |
| 29198 | 02/04/2017 | 3000 |
| 29198 | 02/05/2018 | 250 |
+-------+------------+------------+
Table : Equipment
+-------+-----------+
| EQ_no | Serial no |
+-------+-----------+
| 1006 | MDRSC12 |
| 29198 | FDRSC13 |
| 6218 | REAFC14 |
+-------+-----------+
Result:
+-------+-----------+------+------+------+
| EQ_no | Serial no | 2018 | 2019 | 2020 |
+-------+-----------+------+------+------+
| 1006 | MDRSC12 | 350 | 922 | 500 |
| 29198 | FDRSC13 | 250 | 0 | 0 |
| 6218 | REAFC14 | 0 | 0 | 0 |
+-------+-----------+------+------+------+
If date from 1-jan-2018 to 1-June-2020 then show each years total cost 2018,2019 & 2020.
If date from 1-jan-2020 to 1-June-2021 then show each years total cost of 2020 & 2021 only.
Create a Formula Field that uses the Year() function to extract only the 4 digit numerical year from your Job_Date field. Name this field whatever you like, but I will call it "JobYear" going forward in this answer.
The formula will be Year(Job_Date);.
Now create a second Formula Field that uses the same function to extract the 4 digit numerical year from today's date. I will call this formula field "CurrentYear" going forward.
This formula will be Year(CurrentDate);.
Now create 3 Running Total Fields. Name them something like ThisYear, LastYear, and TwoYearsAgo. Set all three of these fields to summarize the Total_Cost field. Set the reset conditions to whatever is most appropriate for your report, and then set the evaluate conditions to use a formula and use the following formulas for each one.
For ThisYear the formula should be CurrentYear = JobYear;.
For LastYear the formula should be CurrentYear - 1 = JobYear;.
For TwoYearsAgo the formula should be CurrentYear - 2 = JobYear;.
This will allow the running total fields to summarize the total cost for any job into the correct buckets based upon the year the job was completed.

PostgreSQL Crosstab generate_series of weeks for columns

From a table of "time entries" I'm trying to create a report of weekly totals for each user.
Sample of the table:
+-----+---------+-------------------------+--------------+
| id | user_id | start_time | hours_worked |
+-----+---------+-------------------------+--------------+
| 997 | 6 | 2018-01-01 03:05:00 UTC | 1.0 |
| 996 | 6 | 2017-12-01 05:05:00 UTC | 1.0 |
| 998 | 6 | 2017-12-01 05:05:00 UTC | 1.5 |
| 999 | 20 | 2017-11-15 19:00:00 UTC | 1.0 |
| 995 | 6 | 2017-11-11 20:47:42 UTC | 0.04 |
+-----+---------+-------------------------+--------------+
Right now I can run the following and basically get what I need
SELECT COALESCE(SUM(time_entries.hours_worked),0) AS total,
time_entries.user_id,
week::date
--Using generate_series here to account for weeks with no time entries when
--doing the join
FROM generate_series( (DATE_TRUNC('week', '2017-11-01 00:00:00'::date)),
(DATE_TRUNC('week', '2017-12-31 23:59:59.999999'::date)),
interval '7 day') as week LEFT JOIN time_entries
ON DATE_TRUNC('week', time_entries.start_time) = week
GROUP BY week, time_entries.user_id
ORDER BY week
This will return
+-------+---------+------------+
| total | user_id | week |
+-------+---------+------------+
| 14.08 | 5 | 2017-10-30 |
| 21.92 | 6 | 2017-10-30 |
| 10.92 | 7 | 2017-10-30 |
| 14.26 | 8 | 2017-10-30 |
| 14.78 | 10 | 2017-10-30 |
| 14.08 | 13 | 2017-10-30 |
| 15.83 | 15 | 2017-10-30 |
| 8.75 | 5 | 2017-11-06 |
| 10.53 | 6 | 2017-11-06 |
| 13.73 | 7 | 2017-11-06 |
| 14.26 | 8 | 2017-11-06 |
| 19.45 | 10 | 2017-11-06 |
| 15.95 | 13 | 2017-11-06 |
| 14.16 | 15 | 2017-11-06 |
| 1.00 | 20 | 2017-11-13 |
| 0 | | 2017-11-20 |
| 2.50 | 6 | 2017-11-27 |
| 0 | | 2017-12-04 |
| 0 | | 2017-12-11 |
| 0 | | 2017-12-18 |
| 0 | | 2017-12-25 |
+-------+---------+------------+
However, this is difficult to parse particularly when there's no data for a week. What I would like is a pivot or crosstab table where the weeks are the columns and the rows are the users. And to include nulls from each (for instance if a user had no entries in that week or week without entries from any user).
Something like this
+---------+---------------+--------------+--------------+
| user_id | 2017-10-30 | 2017-11-06 | 2017-11-13 |
+---------+---------------+--------------+--------------+
| 6 | 4.0 | 1.0 | 0 |
| 7 | 4.0 | 1.0 | 0 |
| 8 | 4.0 | 0 | 0 |
| 9 | 0 | 1.0 | 0 |
| 10 | 4.0 | 0.04 | 0 |
+---------+---------------+--------------+--------------+
I've been looking around online and it seems that "dynamically" generating a list of columns for crosstab is difficult. I'd rather not hard code them, which seems weird to do anyway for dates. Or use something like this case with week number.
Should I look for another solution besides crosstab? If I could get the series of weeks for each user including all nulls I think that would be good enough. It just seems that right now my join strategy isn't returning that.
Personally I would use a Date Dimension table and use that table as the basis for the query. I find it far easier to use tabular data for these types of calculations as it leads to SQL that's easier to read and maintain. There's a great article on creating a Date Dimension table in PostgreSQL at https://medium.com/#duffn/creating-a-date-dimension-table-in-postgresql-af3f8e2941ac, though you could get away with a much simpler version of this table.
Ultimately what you would do is use the Date table as the base for the SELECT cols FROM table section and then join against that, or probably use Common Table Expressions, to create the calculations.
I'll write up a solution to that if you would like demonstrating how you could create such a query.

In postgresql, how do you find aggregate base on time range

For example, if I have a database table of transactions done over the counter. And I would like to search whether there was any time that was defined as extremely busy (Processed more than 10 transaction in the span of 10 minutes). How would I go about querying it? Could I aggregate based on time range and count the amount of transaction id within those ranges?
Adding example to clarify my input and desired output:
+----+--------------------+
| Id | register_timestamp |
+----+--------------------+
| 25 | 08:10:50 |
| 26 | 09:07:36 |
| 27 | 09:08:06 |
| 28 | 09:08:35 |
| 29 | 09:12:08 |
| 30 | 09:12:18 |
| 31 | 09:12:44 |
| 32 | 09:15:29 |
| 33 | 09:15:47 |
| 34 | 09:18:13 |
| 35 | 09:18:42 |
| 36 | 09:20:33 |
| 37 | 09:20:36 |
| 38 | 09:21:04 |
| 39 | 09:21:53 |
| 40 | 09:22:23 |
| 41 | 09:22:42 |
| 42 | 09:22:51 |
| 43 | 09:28:14 |
+----+--------------------+
Desired output would be something like:
+-------+----------+
| Count | Min |
+-------+----------+
| 1 | 08:10:50 |
| 3 | 09:07:36 |
| 7 | 09:12:08 |
| 8 | 09:20:33 |
+-------+----------+
How about this:
SELECT time,
FROM (
SELECT count(*) AS c, min(time) AS time
FROM transactions
GROUP BY floor(extract(epoch from time)/600);
)
WHERE c > 10;
This will find all ten minute intervals for which more than ten transactions occurred within that interval. It assumes that the table is called transactions and that it has a column called time where the timestamp is stored.
Thanks to redneb, I ended up with the following query:
SELECT count(*) AS c, min(register_timestamp) AS register_timestamp
FROM trak_participants_data
GROUP BY floor(extract(epoch from register_timestamp)/600)
order by register_timestamp
It works close enough for me to be able tell which time chunks are the most busiest for the counter.

Subtract fields of a column - Tableau

I would like to subtract promoters and detractors in Tableau by creating a new column. Thanks for all the help!
Customer Type Table (I would like to create the NPS field as shown below):
+---------+------------+----------+-----------+--------------+
| Quarter | Detractors | Passives | Promoters | NPS |
+---------+------------+----------+-----------+--------------+
| Q1 15 | 40.56 | 23.56 | 35.79 | =35.79-40.56 |
| ... | ... | ... | ... | ... |
+---------+------------+----------+-----------+--------------+
Simply create a calculated field (called NPS):
[Promoters] - [Detractors]
This will add a new field to every row of your partition called NPS.
Check out the Tableau online help on calculated fields - this is a skill well worth learning.
I understand the OPs question. The data comes in like this:
+---------+---------------+------+
| Quarter | Customer Type | Score|
+---------+------------+---------+
| Q1 15 | Detractors | 25 |
| Q1 15 | Promoters | 32 |
| Q1 15 | Passives | 45 |
| Q1 15 | Detractors | 17 |
| Q1 15 | Detractors | 28 |
| ... | ... | ... |
+---------+------------+---------+
And when brought into Tableau, the [Customer Type] field is put in the Column shelf and this arranges the data like the table below. The OP wants to calculate the [NPS] column (Promoters - Detractors).
+---------+------------+----------+-----------+--------------+
| Quarter | Detractors | Passives | Promoters | NPS |
+---------+------------+----------+-----------+--------------+
| Q1 15 | 40.56 | 23.56 | 35.79 | =35.79-40.56 |
| ... | ... | ... | ... | ... |
+---------+------------+----------+-----------+--------------+
I hope this clarifies. I am stuck with a similar situation (I want a column that shows the difference between 2015 and 2016):
+---------+-------+-------+------------+
| Measure | 2015 | 2016 | Difference |
+---------+---------------+------------+
| # Hires | 100 | 115 | 15 |
| # Terms | 9 | 6 | 3 |
+---------+---------------+------------+
I believe the steps are similar. I hope someone can help.