/ / Consulta SQL para juntar tabelas - onde a data / hora de uma tabela não corresponde às outras - sql-server, data / hora

Consulta SQL para unir tabelas - onde a datetime de uma tabela não corresponde às outras - sql-server, datetime

Entrei só para perguntar isso porque está me matando :) Ótimo fórum com muitas mentes incríveis!

Eu simplesmente preciso juntar essas duas tabelas, só posso juntá-las na data e hora em que nenhuma outra coluna estiver disponível.

A Tabela 1 tem por exemplo as seguintes colunas

Filme ----------------- Data e hora …………………………… Duração (minutos)

TITÂNICO ------------ 2016-01-01 01:00:00 ----------------- 60

Armagedom --------- 2016-01-01 02:00:00 ----------------- 60

A Tabela 2 tem as seguintes colunas

Data hora

01-01-2016 ……… .01: 00: 00

01/01/2016 ……… .01: 01: 00

01/01/2016 ……… .01: 02: 00

01-01-2016 ……… .01: 03: 00

…e assim por diante

A Tabela 2 contém informações para cada minuto, mas a tabela um contém apenas uma hora e data específicas por evento. então preciso comparar cada minuto da mesa dois com o que obtive da mesa um.

Alguma ideia? Vou aceitar qualquer coisa que funcione :) A propósito, desculpe pela formatação!

Editar: O resultado desejado seria algo como

TITÂNICO ------------ 2016-01-01 01:00:00 ----------------- 60

TITÂNICO ------------ 2016-01-01 01:01:00 ----------------- 60

TITÂNICO ------------ 2016-01-01 01:02:00 ----------------- 60

Armagedom --------- 2016-01-01 02:00:00 ----------------- 60

Armagedom --------- 2016-01-01 02:01:00 ----------------- 60

Armagedom --------- 2016-01-01 02:02:00 ----------------- 60

E assim por diante...

Respostas:

0 para resposta № 1

Vou fazer algumas suposições, pois você não delineou a estrutura da tabela.

Sua mesa de filme tem a seguinte estrutura:

CREATE TABLE Films ([Film] NVARCHAR(128), [DateTime] DATETIME, Duration INT)
GO

Sua tabela de valores de data / hora tem a seguinte estrutura:

CREATE TABLE DateTimeValues ([Date] DATE, [Time] TIME)
GO

Vamos inserir seus valores:

--Insert Values for Films
INSERT INTO Films
VALUES  ("TITANIC", "2016-01-01T01:00:00", 60),
("Armageddon", "2016-01-01 02:00:00", 60)

GO

--Insert Values for every minute of 2016-01-01
DECLARE @DATETIMEBEGIN DATETIME
SET @DATETIMEBEGIN = "2016-01-01"
DECLARE @DATETIMEEND DATETIME
SELECT @DATETIMEEND = "2016-01-02"

;WITH CTE AS (SELECT DATEADD(day, 0, DATEDIFF(day, 0, @DATETIMEBEGIN)) DateTimeValues
UNION  ALL
SELECT DATEADD(MINUTE, 1, DateTimeValues) AS DateTimeValues
FROM CTE
WHERE DateTimeValues < @DATETIMEEND
)
INSERT INTO DateTimeValues
SELECT  CONVERT(DATE, DateTimeValues) "Date",
CONVERT(TIME, DateTimeValues) "Time"
FROM    CTE
OPTION  (MAXRECURSION 0)
GO

Vamos simplificar e calcular a hora de início / fim de cada filme de acordo com a duração. A consulta necessária para o resultado desejado é:

;WITH CTEFilms AS
(
SELECT  Film,
CONVERT(DATE, [DateTime]) "Date",
CONVERT(TIME, [DateTime]) "StartTime",
CONVERT(TIME, DATEADD(MINUTE,Duration,[DateTime])) "EndTime",
Duration
FROM    Films
)

SELECT      f.Film,
CAST(dtv."Date" AS DATETIME) + dtv."Time" "DateTime",
Duration
FROM        CTEFilms f
INNER JOIN  DateTimeValues dtv
ON f.[Date] = dtv.[Date]
AND dtv.[Time] >= f.StartTime
AND dtv.[Time] < f.EndTime
ORDER BY    Film, Time

Seus resultados:

Film        DateTime                Duration
Armageddon  2016-01-01 02:00:00.000 60
Armageddon  2016-01-01 02:01:00.000 60
Armageddon  2016-01-01 02:02:00.000 60
Armageddon  2016-01-01 02:03:00.000 60
Armageddon  2016-01-01 02:04:00.000 60
...
Armageddon  2016-01-01 02:55:00.000 60
Armageddon  2016-01-01 02:56:00.000 60
Armageddon  2016-01-01 02:57:00.000 60
Armageddon  2016-01-01 02:58:00.000 60
Armageddon  2016-01-01 02:59:00.000 60
TITANIC     2016-01-01 01:00:00.000 60
TITANIC     2016-01-01 01:01:00.000 60
TITANIC     2016-01-01 01:02:00.000 60
TITANIC     2016-01-01 01:03:00.000 60
TITANIC     2016-01-01 01:04:00.000 60
...
TITANIC     2016-01-01 01:55:00.000 60
TITANIC     2016-01-01 01:56:00.000 60
TITANIC     2016-01-01 01:57:00.000 60
TITANIC     2016-01-01 01:58:00.000 60
TITANIC     2016-01-01 01:59:00.000 60

1 para resposta № 2

converta a data e hora da tabela 2 em uma data e hora e veja se está entre data e hora da tabela 1 e data e hora + duração.

SELECT  *
FROM    table1 t1
JOIN table2 t2 ON CAST(t2.Date AS DATETIME)
+ CAST(t2.Time AS DATETIME) >= t1.Datetime
AND CAST(t2.Date AS DATETIME)
+ CAST(t2.Time AS DATETIME) < DATEADD(MIN,
t1.Duration,
t1.Datetime)

0 para resposta № 3

@Eddie B, você não forneceu sua estrutura de tabela, ou seja, tipos de dados de coluna, então acabei de apresentar o seguinte código / dados assumidos

use tempdb
drop table dbo.t1, dbo.t2;
create table dbo.T1 (film varchar(10), dt datetime, duration int)
create table dbo.T2 (dt varchar(10), tm varchar(10));
go

-- populate the tables with SOME sample data

insert into dbo.T1(film, dt, duration)
values ("Titanic", "2016-01-01 01:00:00", 5), ("Amageddon", "2016-01-01 02:00:00", 4)

insert into dbo.T2 (dt, tm)
values
("2016-01-01", "01:00:00")
,  ("2016-01-01", "01:01:00")
,  ("2016-01-01", "01:02:00")
,  ("2016-01-01", "01:03:00")
,  ("2016-01-01", "01:04:00")
,  ("2016-01-01", "01:05:00")

,  ("2016-01-01", "02:00:00")
,  ("2016-01-01", "02:01:00")
,  ("2016-01-01", "02:02:00")
,  ("2016-01-01", "02:03:00")
,  ("2016-01-01", "02:04:00")
,  ("2016-01-01", "02:05:00")

,  ("2016-01-01", "03:00:00");

go

-- here is the result
select t1.film, [DateTime]= convert(datetime,   t2.dt + " " + t2.tm), t1.duration
from dbo.t1
inner join dbo.t2
on convert(datetime,   t2.dt + " " + t2.tm) >= t1.dt
and convert(datetime,   t2.dt + " " + t2.tm) <= dateadd(minute, t1.duration, t1.dt)
go

Aqui está o resultado:

insira a descrição da imagem aqui