I would like to get the output for the over lapping date records
> Data: Id Open_date Closed_Date
> 1 2016-01-01 2017-01-01
**> 1 2016-12-31 2018-21-01
> 1 2016-01-01 2018-01-01**
> 2 2017-01-01 2018-02-02
Here, you see the second & 3rd records are starting with date than the closed_Date of their previous records. Here i need to identify those type of records
As you question is not much clear, I am assuming that you are looking for min of open date and max of close date.
If this is not the requirement edit the question to provide more details.
select id, min(Open_date), max(Closed_Date)
from table
group by id
Looks like you want to normalize a Slowly Changing Dimension Type 2. Of course the best way to handle them would be using Temporal tables using either Teradata or ANSI syntax.
There's a nice syntax in Teradata to get your expected result based on the Period data type, but it's imple to cast your begin/end dates to a period:
SELECT id,
-- split the period back into seperate dates
Begin(pd) AS Open_date,
End(pd) AS Closed_Date
FROM
(
SELECT NORMALIZE -- magic keyword :-)
id, PERIOD(Open_date, Closed_Date) AS pd
FROM tab
) AS dt
Related
I have a sqlite3 database maintained on an AWS exchange that is regularly updated by a Python script. One of the things it tracks is when any team generates a new post for a given topic. The entries look something like this:
id
client
team
date
industry
city
895
acme industries
blueteam
2022-06-30
construction
springfield
I'm trying to create a table that shows me how many entries for construction occur each day. Right now, the entries with data populate, but they exclude dates with no entries. For example, if I search for just
SELECT date, count(id) as num_records
from mytable
WHERE industry = "construction"
group by date
order by date asc
I'll get results that looks like this:
date
num_records
2022-04-01
3
2022-04-04
1
How can I make sqlite output like this:
date
num_records
2022-04-02
3
2022-04-02
0
2022-04-03
0
2022-04-04
1
I'm trying to generate some graphs from this data and need to be able to include all dates for the target timeframe.
EDIT/UPDATE:
The table does not already include every date; it only includes dates relevant to an entry. If no team posts work on a day, the date column will jump from day 1 (e.g. 2022-04-01) to day 3 (2022-04-03).
Given that your "mytable" table contains all dates you need as an assumption, you can first select all of your dates, then apply a LEFT JOIN to your own query, and map all resulting NULL values for the "num_records" field to "0" using the COALESCE function.
WITH cte AS (
SELECT date,
COUNT(id) AS num_records
FROM mytable
WHERE industry = "construction"
GROUP BY date
ORDER BY date
)
SELECT dates.date,
COALESCE(cte.num_records, 0) AS num_records
FROM (SELECT date FROM mytable) dates
LEFT JOIN cte
ON dates.date = cte.date
There is a database in place with hourly timeseries data, where every row in the DB represents one hour. Example:
TIMESERIES TABLE
id date_and_time entry_category
1 2017/01/20 12:00 type_1
2 2017/01/20 13:00 type_1
3 2017/01/20 12:00 type_2
4 2017/01/20 12:00 type_3
First I used the GROUP BY statement to find the latest date and time for each type of entry category:
SELECT MAX(date_and_time), entry_category
FROM timeseries_table
GROUP BY entry_category;
However now, I want to find which is the date and time which is the LEAST RECENT among the datetime's I obtained with the query listed above. I will need to use somehow SELECT MIN(date_and_time), but how do I let SQL know I want to treat the output of my previous query as a "new table" to apply a new SELECT query on? The output of my total query should be a single value—in case of the sample displayed above, date_and_time = 2017/01/20 12:00.
I've tried using aliases, but don't seem to be able to do the trick, they only rename existing columns or tables (or I'm misusing them..).There are many questions out there that try to list the MAX or MIN for a particular group (e.g. https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ or Select max value of each group) which is what I have already achieved, but I want to do work now on this list of obtained datetime's. My database structure is very simple, but I lack the knowledge to string these queries together.
Thanks, cheers!
You can use your first query as a sub-query, it is similar to what you are describing as using the first query's output as the input for the second query. Here you will get the one row out put of the min date as required.
SELECT MIN(date_and_time)
FROM (SELECT MAX(date_and_time) as date_and_time, entry_category
FROM timeseries_table
GROUP BY entry_category)a;
Is this what you want?
SELECT TOP 1 MAX(date_and_time), entry_category
FROM timeseries_table
GROUP BY entry_category
ORDER BY MAX(date_and_time) ASC;
This returns ties. If you do not want ties, then include an additional sort key:
SELECT TOP 1 MAX(date_and_time), entry_category
FROM timeseries_table
GROUP BY entry_category
ORDER BY MAX(date_and_time) ASC, entry_category;
I have a database with electricity meter readings. Sometimes people get a new meter and then their original meter gets an end date and the new meter gets a start date and the end date remains NULL. This can happen multiple times in a year and I want to know if there are no gaps in measurement. In other words, I need to figure out if end date 1 is the same as start date 2 and so on.
Sample data:
cust_id meter_id start_date end_date
--------------------------------------------------
a 1 2017-01-01 2017-05-02
a 2 2017-05-02 Null
b 3 2017-01-01 2017-06-01
b 4 2017-06-05 Null
This is what the data looks like and the result I am looking for is that for customer a the end date of meter 1 is equal to the start date of meter 2. For customer b however, there are 4 days between the end date of meter 3 and the start date of meter 4. That is something I want to flag.
I found customers for whom this can happen up to 8 times in the period I am researching. I tried something with nested queries and very complex cases but even I lost my way around it, so I was wondering if someone here has an idea of how to get to the answer a little smarter.
You can get the offending rows using lag():
select r.*
from (select r.*,
lag(end_date) over (partition by cust_id, meter_id order by start_date) as prev_end_date,
row_number() over (partition by cust_id, meter_id order by start_date) as seqnum
from readings r
) r
where prev_end_date <> start_date or prev_end_date is null and seqnum > 1;
Guessing there is now a better way to pull this off using LEAD and LAG, but I wrote an article in SQL 2008R2 called T-SQL: Identify bad dates in a time series where you can modify the big cte in the middle of the article to handle your definition of a bad date.
Good luck. There's too much detail in the article to post in a single SO question, otherwise I'd do that here.
I am writing a query and am having trouble filtering data as I would like. In the table, there is a date field and an ItemCode field. I would like to return one record per ItemCode with the earliest date that is after today.
If today is 6/6/2017 and my data looks like:
ItemCode Date
1 6/1/2017
1 6/7/2017
1 6/10/2017
2 6/2/2017
2 6/8/2017
2 6/15/2017
I would want the result to be
ItemCode Date
1 6/7/2017
2 6/8/2017
My query so far is:
SELECT PO_PurchaseOrderDetail.ItemCode, Min(PO_PurchaseOrderDetail.RequiredDate) AS NextPO
FROM PO_PurchaseOrderDetail
GROUP BY PO_PurchaseOrderDetail.ItemCode
HAVING (((Min(PO_PurchaseOrderDetail.RequiredDate))>=Now()));
The problem is that the Min function fires first and grabs the earliest dates per ItemCode, which are before today. Then the >=Now() is evaluated and because the min dates are before today, the query returns nothing.
I've tried putting the >=Now() inside the min function in the HAVING part of the query but it does not change the result.
My structure is wrong and I would appreciate any advice. Thanks!
I would approach like this for standard SQL, Access approach may vary
select PO_PurchaseOrderDetail.ItemCode,
min(PO_PurchaseOrderDetail.RequiredDate) as NextPO
from PO_PurchaseOrderDetail
where PO_PurchaseOrderDetail.RequiredDate >= Now()
group by PO_PurchaseOrderDetail.ItemCode;
Put the date condition in the where clause (not the having clause):
select ItemCode, min(Date) as NextPO
from PO_PurchaseOrderDetail
where Date > '6/6/2017'
group by ItemCode
I have one SQL output table like this
ITEM,LOC,PERIOD,QUANTITY
101,US,07/22/2015,500
101,US,07/02/2015,0
102,LON,07/22/2015,0
102,LON,07/02/2015,1000
But I want the output table as follows,
ITEM LOC 07/22/2015 07/02/2015
101 US 500 0
102 LON 0 1000
Please find the code which I have used below,
select * from
(
select item, loc, period, quantity
from example
)
pivot
(
sum (quantity) for period in ('22/JUL/2015','02/JUL/2015'));
If it is for 2 dates, then no issue in mentionning the 'IN' clause
If it is 1000 dates like weekly, monthly and daily. Then how ?
Below command is not working in 'IN' clause.
SELECT PERIOD FROM EXAMPLE WHERE PERIOD < TO_DATE(22/JUL/2015);
Can you please help me to solve this issue ?
Thanks for your time.
Your issue may be incompatible data types. If the period column on your table is DATE type, you are trying to compare strings/VARCHAR with DATE type.
If period column is a DATE try changing your IN to
SELECT period FROM example WHERE period < DATE '2015-07-22';
or
SELECT period FROM example WHERE period < TO_DATE('22/JUL/2015', 'DD/MON/YYYY');