I have a table that contains a DateField(DataType : DateTime) and TimeField(DataType : Float)
My output should be DateTime . My tables are in SQL Server 2008
Here is an example :
Table A
ID StartDate StartTime
1 2012-06-08 00:00:00.000 1223
2 2012-08-07 00:00:00.000 910
3 2012-05-02 00:00:00.000 1614
4 0094-07-13 00:00:00.000 1245
5 1994-04-18 00.00:00.000 2573
I need to get my output in such a way that I should it should validate for the correct time and correct date and append these two and insert into table B
Table B :
ID StartDateTime
1 2012-06-06 12:23:00.000
2 2012-08-07 09:10:00.000
3 2012-05-02 16:14:00.000
Note that I intentionally left rows 4 and 5 out of the result set; these rows should be ignored because they don't contain valid datetime or time data.
Have you considered correcting the design, and storing the date/time together, or at least storing date and time using the proper data types? In the meantime:
SELECT StartDate + STUFF(RIGHT('0' + RTRIM(StartTime), 4), 3, 0, ':')
FROM dbo.table
WHERE ISDATE(StartDate) = 1 AND CONVERT(INT, StartTime) < 2400
-- wow what a bunch of absolute garbage data you have
-- what Government agency are you paying to provide this data?
AND CONVERT(INT, StartTime) % 100 BETWEEN 0 AND 59;
Related
I have a Dimension table containing machines.
Each machine has a date created value.
I would like to have a Select statement that generates for each day after a certain start date the available number of machines. A machine is available after the date created on wards
As I have read only access to the database I am not able to create a physical calendar table
I hope somebody can help me solving my issue
I assume this is what you want. Based on this sample table:
USE tempdb;
GO
CREATE TABLE dbo.Machines
(
MachineID int,
CreatedDate date
);
INSERT dbo.Machines VALUES(1,'20200104'),(2,'20200202'),(3,'20200214');
Then say you wanted the number of active machines starting on January 1st:
DECLARE #StartDate date = '20200101';
;WITH x AS
(
SELECT n = 0 UNION ALL SELECT n + 1 FROM x
WHERE n < DATEDIFF(DAY, #StartDate, GETDATE())
),
days(d) AS
(
SELECT DATEADD(DAY, x.n, #StartDate) FROM x
)
SELECT days.d, MachineCount = COUNT(m.MachineID)
FROM days
LEFT OUTER JOIN dbo.Machines AS m
ON days.d >= m.CreatedDate
GROUP BY days.d
ORDER BY days.d
OPTION (MAXRECURSION 0);
Results:
d MachineCount
---------- ------------
2020-01-01 0
2020-01-02 0
2020-01-03 0
2020-01-04 1
2020-01-05 1
...
2020-01-31 1
2020-02-01 1
2020-02-02 2
2020-02-03 2
...
2020-02-12 2
2020-02-13 2
2020-02-14 3
2020-02-15 3
Clean up:
DROP TABLE dbo.Machines;
(Yes, some people hiss at recursive CTEs. You can replace it with any number of set generation techniques, some I talk about here, here, and here.)
I used following queries to get date from one table and insert into another table.
INSERT INTO InstallmentPaymentHistory
VALUES('DateSold')
SELECT CONVERT(VARCHAR(11), s.DateSold, 113) AS DateSold
FROM SalesInvoice s
WHERE s.SalesInvoiceID = 9;
but I get an error
Conversion failed when converting date and/or time from character string
I have also tried
INSERT INTO InstallmentPaymentHistory
VALUES('YYYY.MM.DD')
SELECT CONVERT(VARCHAR(11), s.DateSold, 113) AS DateSold
FROM SalesInvoice s
WHERE s.SalesInvoiceID = 9;
But I get the same error.
Table #1
SalesInvoiceID CustomerID SoldDate TotalBill
-------------------------------------------------------
1 3840 2018.03.22 20000
2 4581 2018.04.11 80000
3 4420 2018.05.13 60000
Table # 2
InstallmentPaymentID SalesInvoiceID InstallmentNo DueDate PaymentDdate
---------------------------------------------------------------
1 2 1 2018.03.22 2018.3.22
2 2 2 2018.04.11 2018.3.22
3 2 3 2018.05.13 2018.3.22
Not entirely clear what you're trying to do with those commands......
If you want to use the SELECT, combined with some fixed values, then you should use something like this:
INSERT INTO dbo.InstallmentPaymentHistory (specify-the-list-of-columns-here!)
SELECT
-- provide the fixed values here, first
11, 9, 2, 'DateSold', '20180306', 6000,
-- then the "calculated/converted" value from your other table
CONVERT(VARCHAR(11), s.DateSold, 113)
FROM
dbo.SalesInvoice s
WHERE
s.SalesInvoiceID = 9;
Also: it's not clear from your post whether the date string 2018.3.6 refers to the 3rd of June or the 6th of March - but I'd recommend to always use the adapted ISO-8601 format, which is YYYYMMDD (without any dashes or anything!).
So for 6th of March, use 20180306, and for 3rd of June use 20180603
I have table containing branch id and branch starttime and endtime
BRANCHID SHIFTID STARTTIME STOPTIME
1 1 1900-01-01 00:01:00.000 1900-01-01 23:58:00.000
4 4 1900-01-01 07:30:00.000 1900-01-01 18:00:00.000
5 5 1900-01-01 06:30:00.000 1900-01-01 19:00:00.000
6 6 1900-01-01 06:30:00.000 1900-01-01 17:00:00.000
7 7 1900-01-01 00:30:00.000 1900-01-01 18:00:00.000
Now i want to get the number of hours in date range like :
BRANCHID Hours
1 1
1 2
1 3
. .
. .
The resultant table containing branch id and hours in time interval. like branch 1 start time is 00:01:00 - 23:58:00. Than branch id 1 time interval contains following hours 1,2,3,4,5,6 and so on..
select
branchid from table t1
cross apply
(
select n from numbers
where n >=datepart(hour,starttime) and n<=datepart(hour,stoptime)
) b
Below are some links on the numbers table used..
1.http://dataeducation.com/you-require-a-numbers-table/
2.https://dba.stackexchange.com/questions/11506/why-are-numbers-tables-invaluable
Create temp table #hours.
create table #Hours
(
BId int,
[Hour] int
)
Get max and min datetime.
While (#minDateTime < #maxDateTime)
begin
insert into #Hours values (#brID,Datepart(hour,#minDateTime))
set #minDateTime = DATEADD(hh,1,#minDateTime)
end
Select * from #Hours
ID DateTime Code
---------- -------------- ----------
58 2015-01-01 20:00:00 1111
58 2015-01-11 10:00:00 8523
58 2015-01-11 03:00:00 4555
58 2015-01-19 00:01:00 8888
9 2015-01-01 20:00:00 4444
how do i count the number of codes for a specific ID ignoring which date it is but it must be between 20:00:00 and 06:00:00
select count(code) as count from table 1 where ID='58' and DateTime between '20:00:00' and '06:00:00'
the expected output would be
count
3
SELECT count(code) as count
FROM table1
WHERE
ID='58' and
(CAST(DateTime as time) >= '20:00'
or CAST(DateTime as time) <= '06:00')
EDIT: John, I understand the issue. Here is a full solution to handle those cases:
In order to use variables:
DECLARE #HourBegin time = '07:00'
DECLARE #HourEnd time = '17:30'
SELECT count(code) as count
FROM table1
WHERE
ID='58' and
(CAST(DateTime as time) between #HourBegin and #HourEnd or
((CAST(DateTime as time) <= #HourEnd or
CAST(DateTime as time) >= #HourBegin) and
#HourBegin > #HourEnd)
)
Almost the same as previous answer, but with hours it looks nicer for me and might be you need DISTINCT code
SELECT count(DISTINCT code) as count
FROM table1
WHERE
ID='58' and
(DATEPART(HOUR,DateTime) >= 20
or DATEPART(HOUR,DateTime) < 6)
UPDATED: changed from <= 6 to < 6
Update
This answer applies to MySQL.
When I started writing the answer, the question was tagged mysql and sql-server. The OP edited it in the meantime.
This query should do what you want on MySQL.
SELECT count(code) AS `count`
FROM `table 1`
WHERE ID='58'
AND TIME(`DateTime`) NOT BETWEEN '06:00:01' AND '19:59:59'
The MySQL function TIME() extracts only the time component from a DATETIME value.
On version 5.7, MySQL added support for fractional seconds (up to 6 digits) on DATETIME columns. The query above will include the entries having time greater than 06:00:00 but smaller than 06:00:01 (events that happened during the first second after 6 AM sharp).
For MySQL 5.7 and newer, the correct query is:
SELECT count(code) AS `count`
FROM `table 1`
WHERE ID='58'
AND (TIME(`DateTime`) <= '06:00:00' OR '20:00:00' <= TIME(`DateTime`))
I don't know about SQL Server.
I have a sql query that is grouping rows by calendar week
select count(*),datepart(wk,mydate)
from MyTable
where mydate between '12/26/2010' and '1/8/2011'
group by datepart(wk,mydate)
The date range is two weeks but three rows come back because Jan 1 is a saturday and is the only day in the range that DATEPART returns a 1 the other dates return 53 or 2.
I want jan 1 to be grouped with the dates that return a 53, but I want it to be a generic answer not something like CASE WHEN datepart(wk,mydate) = 53 then 1 else datepart(wk,mydate) end because that will work for that specific date range not for other years.
I'm just wondering what a good solution would be
thanks in advance.
We use to choose as week of a date, the week of his last sunday (first day of the week in SQL). So, for each date, you can ask for the week of his last sunday with the following query:
select count(*),datepart(wk,mydate-DATEPART(dw,mydate)+1)
from MyTable
where mydate between '12/26/2010' and '1/8/2011'
group by datepart(wk,mydate-DATEPART(dw,mydate)+1)
Perhaps you can use iso_week instead of wk.
select count(*),datepart(iso_week,mydate)
from MyTable
where mydate between '12/26/2010' and '1/8/2011'
group by datepart(iso_week,mydate)
Sample:
declare #T table (Val datetime)
insert into #T values
('2010-12-30'),
('2010-12-31'),
('2011-01-01'),
('2011-01-02'),
('2011-01-03'),
('2011-01-04'),
('2011-01-05')
select
Val,
datepart(iso_week, Val) as ISO_WEEK
from #T
Result:
Val ISO_WEEK
----------------------- -----------
2010-12-30 00:00:00.000 52
2010-12-31 00:00:00.000 52
2011-01-01 00:00:00.000 52
2011-01-02 00:00:00.000 52
2011-01-03 00:00:00.000 1
2011-01-04 00:00:00.000 1
2011-01-05 00:00:00.000 1
Try DateDiff() instead with your start date as the date to compare.