Grouping rows with each different row has header row SQL Server - sql

I am trying to group some data in SQL Server. However not sure if there is a query that can do this. Below is the original data
Type Number Date Result
Car 6664441111 Feb 22 2016 IVR Detected
Car 6664441111 Feb 22 2016 Answered
Lab 5552221111 Feb 22 2016 No Answer
Lab 5552221111 Feb 22 2016 Hangup
Lab 5552221111 Feb 22 2016 Answered
I would like to know a query that can do this:
Type Number Date Result
Car 6664441111 Feb 22 2016 IVR Detected
6664441111 Feb 22 2016 Answered
Lab 5552221111 Feb 22 2016 No Answer
5552221111 Feb 22 2016 Hangup
5552221111 Feb 22 2016 Answered
I am using SQL Server. Thank you in advance

Assuimg your data is sorted already and doesn't need to be sorted to make your logic happen you could use a row_number window function:
select
CASE WHEN row_num = 1 THEN type END AS type, number, date, result
from (
select type, number, date, result, row_number() over (partition by type) AS row_num
from t
) x
If you need to order your data to appear like in your example, you need to add order by within window function.

Related

SQL generate a table, count or function for graph

Firstly I have no code to show (but for good reason). I need a pointer or direction before I try again as I have failed a few times already trying to create a recursive function and so on. Kind of given up and thought I would ask you experts as I am lost and stressed.
My Scenario is this.
Im creating a graph in PHP using Json and thats all fine. However the data I need is my issue.
I have records that have a start and an end date.
Example
ID 14
Start_Date 03/08/2021
End_Date 07/08/2021
Running a stored procedure to grab a records and count between 1 Aug to 10 Aug would display the above as a single record.
Im trying to create a line chart that would have 1 Aug to 2 Aug null then 3 Aug through 7 Aug displaying 1 and finally 8 to 10 Aug null.
1 Aug 2021 0
2 Aug 2021 0
3 Aug 2021 1
4 Aug 2021 1
5 Aug 2021 1
6 Aug 2021 1
7 Aug 2021 1
8 Aug 2021 0
9 Aug 2021 0
10 Aug 2021 0
Is this possible as I have nearly given up.
The nearest I came was using a loop to create a temporary table and inserting records was NOT pretty and certain was embarrassing. If I recreated and posted it here I would die of shame for sure.
So if anyone can point me in the right direction, offer a suggestion or anything like this would be very much appreciated.
Thank you for reading.
You need to start with a list of dates. There are many ways to generate such a list -- perhaps you have an existing table, or your database supports a function. SQL (in general) supports recursive CTEs, which is an alternative method.
Once you have the dates, you can use left join and group by to get the counts you want. Here is an example using MySQL syntax:
with recursive dates as (
select date('2021-08-01') as dte
union all
select dte + interval 1 day
from dates
where dte < '2021-08-10'
)
select d.dte, count(t.id)
from dates d left join
t
on d.dte between t.start_date and t.end_date
group by d.dte;
Here is a db<>fiddle.

Convert string to date SSRS

I have issue converting parameter string to date.
I have list of data as:
Jul 28 2017 Call
Jan 8 2018 SMS
Apr 24 2018 Call
Jul 2 2018 E-Mail
Jul 13 2018 Call
Oct 1 2018 Call
Nov 27 2018 E-Mail
Dec 31 2018 Call
Jan 1 2019 SMS
Apr 1 2019 SMS
Jun 4 2019 SMS
I want them to be presented as eg. 06/04/2019 if possible
I tried LSet(Format(Parameters!DateInfo.Label,"MM/dd/yyyy"),12) in expression, but when I run the report it is showing me just like this MM/dd/YYYY.
For your parameter, you probably should be using a dataset for the dates with the Value set to use a date field and the Label using the string representation of the date (CONVERT(CHAR(10), THEDATE, 110) AS DATE_LABEL).
I'm guessing the user isn't typing the parameter values in which means that there's already a dataset for the dates. Add another column to the dataset with the date as a date field to use as the Value while using the text as the Label.
If you cannot fix that and still need to convert the text field into a date, you could use the CDATE function which will convert text into a date field.
=Format(CDATE(LEFT(Parameters!DateInfo.Label, 12)),"MM/dd/yyyy")

Get the latest date in SQL from text format

I'm trying to get the latest date from a csv file , the dates are stored in this form
NOV 14 2010
FEB 1 2012
JUN 18 2014
and my query is like
SELECT Max(date) from table
I'm getting
NOV 14 2010
any idea ?
They are likely being considered strings(varchar) not DateTimes. Try:
SELECT MAX(CAST(TABLE.date as DateTime)) FROM TABLE

MS Access grouping query spanning start and end dates

I would like to get a running tally of how many widgets were/are rented at any one time, by month, by year. Data is held in an MS Access 2003 db;
Table name: rent_table
Fields:
rentid
startdate
enddate
rentfee
rentcost
bookingfee
Something like; Count number of rentid's that fall between month/year, then group them?
e.g. if a widget was rented from 5th Jan 2014 to 8th April 2014 it would appear as a count in Jan, Feb, Mar and April tally's.
Many thanks.
EDIT
More details (sorry);
Access db is fronted by classic ASP.
If possible I don't want to create any new tables.
No input is required in order to run the report.
There are around 350-400 widgets that could be rented at any one time.
Each widget is rented exclusively.
Report output example;
Month | Year | NumRented
Jan 2014 86
Feb 2014 113
...
Can a query pick up dates within dates? So literally do a count of the table where date >Dec 31st 2013 AND <1st Feb 2014 (to grab a count for all of January 2014) and would that include the example of the rent starting on the 5th Jan? So I could just do twelve counts for each year?
create a calendar table, e.g.
table = cal_yyyymm with one column dt_yyyymm as numeric field
populate the table with ... say 5 or 10 years of data
201401 201402 201403 ... 60 or 120 rows, a small table
make a sql
Select
dt_yyyymm,
count(*) as cnt
From cal_yyyymm
Left Join rent_table
On format(startdate,"yyyymm") >= dt_yyyymm
And dt_yyyymm >= format(enddate,"yyyymm")
think about the complications in the data -- --
widget was rented from 5th Jan 2014 to 8th Jan 2014
and again rented from 11th Jan 2014 to 21st Jan 2014
does this count at 1 or 2 in the month?
if it is 1, then the sql gets more complicated because
the rent_table first needs to have its dates converted
to yyyymm format, and second needs to be de-duped on rentid,
and third then joined to cal_ On the dates...

Partition By Clause is giving different results due to ORDER BY clause

I am trying to run a partition query on a sample data.It's giving me different results if I remove ORDER BY clause.What is the reason for different results.Please check the below link.
http://www.sqlfiddle.com/#!4/a0f10/5
SELECT MAX(B1.ET) OVER(PARTITION BY B1.MAS_DIV_KEY,B1.STN_KEY,B1.SBSC_GUID_KEY ORDER BY B1.ST)AS TEST_COL
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1;
SELECT MAX(B1.ET) OVER(PARTITION BY B1.MAS_DIV_KEY,B1.STN_KEY,B1.SBSC_GUID_KEY)AS TEST_COL1
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1;
When you have an order by inside the OVER() clause for aggregations that aren't normally sensitive to sorting (min, max, stdev, etc...) it becomes a running subtotal. See Justin Cave's answer to the question below for a more thorough treatment.
Oracle MIN as analytic function - odd behavior with ORDER BY?
EDIT
Referring to the sqlfiddle here:
http://www.sqlfiddle.com/#!4/a0f10/33
The first query:
SELECT B1.ST
, B1.ET
, MAX(B1.ET)
OVER(PARTITION BY B1.MAS_DIV_KEY
,B1.STN_KEY
,B1.SBSC_GUID_KEY
ORDER BY B1.ST
) AS TEST_COL
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1
ORDER BY B1.ST;
... returns
ST ET TEST_COL
March, 28 2012 11:00:00-0700 March, 28 2012 11:05:00-0700 March, 28 2012 11:05:00-0700
March, 28 2012 11:03:00-0700 March, 28 2012 11:15:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:03:00-0700 March, 28 2012 11:50:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:10:00-0700 March, 28 2012 11:30:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:20:00-0700 March, 28 2012 11:50:00-0700 March, 28 2012 11:50:00-0700
So let's break this down... The first row is a distinct ST so the MAX up to that point is whatever is in that row. Next row, the ST is not unique. So the MAX for all rows up to that point is not 11:15, but rather 11:50 for BOTH rows with ST 11:03. The final two rows never have ET after 11:50, so that's what we show for all remaining rows. We've used the ORDER BY in the OVER clause, so that's what we told Oracle to do.
Oracle documentation for analytic functions says:
*If you omit the windowing_clause entirely, then the default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.*
If you understand how RANGE works it should be clear why you are seeing such results.