T-SQL Convert DateTime and Count entries for each date - sql

I am lost on how to solve what I believe should be a simple query.
I want to count the number of entries for each date in a table. The column DateCreated is in DateTime format. I can convert the datetime to date using
convert(VARCHAR, JobApps.DateCreated, 2) as Date
but with COUNT(ID) as Qty I get a count of 1 with multiple "Date" rows.
Here is the SQL query I am using.
SELECT
convert(VARCHAR, DateCreated, 2) as Date, COUNT(CompanyName) as Qty
FROM Apps
GROUP BY DateCreated
ORDER BY DateCreated DESC
This is the results I get.
Date Qty
------------------
13.05.29 1
13.05.29 1
13.05.29 1
13.05.29 1
13.05.29 1
13.05.28 1
13.05.28 1
13.05.27 1
13.05.27 1
etc...
What I wanting is a result like this...
Date Qty
-----------------
13.05.29 5
13.05.28 2
13.05.27 2
etc...

Just gotta change your GROUP BY to use the actual value you want:
SELECT convert(VARCHAR, DateCreated, 2) as Date, COUNT(1) as Qty
FROM Apps
GROUP BY convert(VARCHAR, DateCreated, 2)
ORDER BY Date DESC

Related

Oracle: How to get first returned record and previous record

I want to grab the first returned record and previous record based on a user input date.
CustNo Food Date
1 Red-Apple 7/5/22
1 Red-Apple 7/5/22
1 Red-Apple 7/11/22
1 Red-Cherry 5/20/22
1 Blue-Muffin 4/1/22
1 Blue-Berry 3/16/22
1 Orange-Persimmon 2/8/22
1 Red-Apple 1/23/22
1 Blue-Berry 12/4/21
1 Yellow-Banana 11/27/21
Example, I put in 7/5/22, and I want to grab that date's food value and somehow include the record previous to that, so output would be:
1 Red-Apple 7/5/22
1 Red-Apple 7/5/22
If I put in 3/16/22, then I want my output to be:
1 Blue-Berry 3/16/22
1 Orange-Persimmon 2/8/22
My totally wrong code:
select CustNo, Food, prevDate
from (
select CustNo, Food, Date
lag(Date) over (partition by CustNo order by Date) as prevDate,
max(Date) over (partition by CustNo) as maxDate
from tableZ
)
where maxDate = Date
and CustNo = 1
and Date = &user_input_date;
Simply select the rows where the date is equal to or less than the decided date, read descending, fetch 2 rows only.
select CustNo, Food, Date
from tableZ
where Date <= &user_input_date
order by Date desc
fetch first 2 rows only
Note: Date is an Oracle reserved word (https://en.wikipedia.org/wiki/SQL_reserved_words), so it needs to be delimited as "Date".

Selecting the difference between dates in a stored procedure using a subquery

I can't get my head around whether this is even possible, but I feel like I might have done it before and lost that bit of code. I am trying to craft a select statement that contains an inner join on a subquery to show the number of days between two dates from the same table.
A simple example of the data structure would look like:
Name ID Date Day Hours
Bill 1 3/3/20 Thursday 8
Fred 2 4/3/20 Monday 6
Bill 1 8/3/20 Tuesday 2
Based on this data, I want to select each row plus an extra column which is the number of days between the date from each row for each ID. Something like:
Select * from tblData
Inner join (datediff(Select Top(1) Date from tblData where Date < Date), Date) And ID = ID)
or for simplicity:
Select * from tblData
Inner join (datediff(Select Top(1) Date from tblData where Date < 8/3/20), 8/3/20) And ID = 1)
The resulting dataset would look like:
Name ID Date Day Hours DaysBtwn
Bill 1 3/3/20 Thursday 8 4 (Assuming there was an earlier row in the table)
Fred 2 4/3/20 Monday 6 5 (Assuming there was an earlier row in the table)
Bill 1 8/3/20 Tuesday 2 5 (Based on the previous row date being 3/3/20 for Bill)
Does this make sense and am I trying to do this the wrong way? I want to do this for about 600000 rows in table and therefore efficiency is the key, so if there is a better way to do this, i'm open to suggestions.
You can use lag():
select t.*, datediff(day, lag(date) over(partition by id order by date), date) diff
from mytable t
I think you just want lag():
select t.*,
datediff(day,
lag(date) over (partition by name order by date),
date
) as diff
from tblData t;
Note: If you want to filter the data so rows in the result set are used for the lag() but not in the result set, then use a subquery:
select t.*
from (select t.*,
datediff(day,
lag(date) over (partition by name order by date),
date
) as diff
from tblData t
) t
where date < '2020-08-03';
Also note the use of the date constant as a string in YYYY-MM-DD format.

Grouping by two parameters in SQL Server

I have a table with this structure:
id | timestamp | barcode
The timestamp is datetime and the barcode is a full barcode, from which I need only the first 9 digits.
I need to get the count for each product for each day with one query.
So I basically need a result like:
date | item number | count
-----------+-------------+--------
12.02.2019 | 827384950 | 32
Item number is left(barcode, 9).
You can try below - using cast() to convert timestamp to date and then add that in group by
select cast([timestamp] as date),left(barcode, 9) as itemnumber,count(*)
from tablename
group by cast([timestamp] as date),left(barcode, 9)
this query has better performance
select date, itemnumber, count(*) from
(select cast([timestamp] as date) as date,left(barcode, 9) as itemnumber
from tablename) a
group by date,itemnumber

Count the number of the time records appears in 48 hrs- SQL

How do we select the count of the record that appears more than once in 48hrs?
for eg
ID DATE
1 9/24/2018
1 9/23/2018
1 9/20/2018
2 9/20/2018
ID 1 APPEARED MORE THAN ONCE IN 48 HOURS
please let me know how to write a sql query to do this
There are lots of ways, but I'd start with using LAG() and a date comparison. Assuming your DATE column is a date data-type?
WITH
entity_summary AS
(
SELECT
ID,
CASE
WHEN LAG("DATE") OVER (PARTITION BY ID ORDER BY "DATE") >= "DATE" - INTERVAL '2' DAY
THEN 1
ELSE 0
END
AS occurence_within_2_day
FROM
Table1
)
SELECT
ID,
SUM(occurence_within_2_day)
FROM
entity_summary
GROUP BY
ID
HAVING
SUM(occurence_within_2_day) >= 1

order unique accounts by date

I have a table:
create table remote (account int ,datecreated datetime,status int)
insert into remote (account , datecreated,status)
values
(123,'2015-08-25',1),
(123,'2015-08-25',1),
(123,'2015-09-26',1),
(1238,'2015-08-25',1),
(123,'2014-08-25',1),
(123,'2014-08-26',1),
(1238,'2014-08-25',1),
(1238,'2014-08-25',1),
(1235,'2014-08-25',1),
(1234,'2014-09-22',1),
(1234,'2014-09-22',1),
(1234,'2014-10-29',1),
(1236,'2014-10-25',1);
From here I would like to get the unique account count for each month/year where status=1
For example using the data above:
the output would be
count | month
-------------
1 |9/2015
2 |8/2015
2 |10/2014
1 |9/2014
3 |8/2014
How can I make this work?
I use sql 2012.
Use Group by month and year of datecreated to skip day part in count. use the same month and year in order by desc . Then Concatenate the month and year to get the result
SELECT [Count],
[Mon/Year]= CONVERT(VARCHAR(2), [Month]) + '/' + CONVERT(VARCHAR(4), [year])
FROM (SELECT [year]=Year(datecreated),
[month]= Month(datecreated),
[Count]= Count(distinct account)
FROM remote
GROUP BY Year(datecreated),
Month(datecreated)) a
ORDER BY [year] DESC,[Month] DESC
Result
Count Mon/Year
----- --------
1 9/2015
3 8/2015
2 10/2014
1 9/2014
5 8/2014
This is a group by query with a filter and some datetime logic:
select year(datecreated) as yr, month(datecreated) as mon, count(*)
from remote
where status = 1
group by year(datecreated), month(datecreated)
order by yr desc, mon desc;
This puts the year and month into separate columns. You can concatenate them together into a single value if you really want to.