INSERT INTO SELECT query that includes the GETDATE() function - sql

I have an INSERT INTO SELECT statement (below) that works fine but I can't figure out how to also populate a datetime field in tbl named rundate.
In other words, I want: INSERT INTO tbl (title,invnum,rundate) where rundate will get the value returned by the GETDATE() function.
INSERT INTO tbl (title,invnum)
SELECT #title,t1.invnum FROM #InvenNums t1 WHERE NOT EXISTS (
SELECT title,invnum FROM tbl t2
WHERE t2.invnum=t1.invnum AND t2.title=#title)

Is this what you want?
INSERT INTO tbl (title, invnum, rundate)
SELECT #title, t1.invnum, GETDATE()
FROM #InvenNums t1
WHERE NOT EXISTS (SELECT 1 FROM tbl t2 WHERE t2.invnum = t1.invnum AND t2.title = #title);

Related

Update column with incremental date based on id

I have table T1:
Id Invoice Date
1 A100
2 B100
I want to update table T1 with incremental date based on ID
Desired result:
Id Invoice Date
1 A100 GetDate()
2 B100 GetDate()+1
Is there something available like this:
update T1
set [Date]= GetDate() + ROW_NUMBER() over (order by id)
from T1
Using a similar, but more direct approach as Larnu, you can update a CTE directly:
WITH cte AS
(
SELECT *
, ROW_NUMBER() over (order by id) rn
FROM T1
)
UPDATE cte
SET [date] = DATEADD(DAY, rn, GETDATE())
Is this what you are looking for ? update the date column based on id
update T1
set [Date]= GetDate() + (id-1)
from T1
One method would be to use a CTE to evaluate the new dates with ROW_NUMBER and DATEADD and then UPDATE using the values from the CTE:
USE Sandbox;
GO
CREATE TABLE TestTable (ID int IDENTITY, SomeDate date)
INSERT INTO dbo.TestTable (SomeDate)
VALUES (GETDATE()),(GETDATE()),(GETDATE()),(GETDATE()),(GETDATE());
GO
SELECT *
FROM TestTable;
GO
WITH NewDates AS(
SELECT ID, DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY TT.ID), GETDATE()) AS NewDate
FROM dbo.TestTable TT)
UPDATE TT
SET SomeDate = ND.NewDate
FROM dbo.TestTable TT
JOIN NewDates ND ON TT.ID = ND.ID;
GO
SELECT *
FROM TestTable;
GO
DROP TABLE TestTable;
GO
use dateadd
update T2
SET T2.D=dateadd(dd,T3.rn,getdate())
FROM
T1 as t2 INNER JOIN
(
select *,ROW_NUMBER() over (order by [id]) as rn from T1
) T3 ON t2.id=t3.id
Use recursive cte to generate Id and dates and then join your table based on Id column to update the dates
with cte as (
select 1 AS Id, getdate() as dt
union all
select cte.Id+1, dateadd(d,1,cte.dt)
from cte
where cte.Id < (SELECT MAX(ID) FROM T1)
)
UPDATE T1
SET T1.Date = cte.dt
FROM T1 INNER JOIN cte ON T1.Id = cte.Id
you can not use Windowed functions directly in update query. you should store logic in some temporary table and then use that value in your update query. One way could be like below.
;with cte as
(
select id,Invoice,dateadd(DAY, ROW_NUMBER() over (order by id), GetDate()) as dt
from T1
)
update a
set a.[date]= cte.dt
from T1 a join cte on cte.id=a.id
where a.id=cte.id

Sum union values

I am trying to sum two values across a UNION. Like:
SELECT
sum(target_value) FROM table
UNION ALL
SELECT
sum(target_value) FROM table_2
But rather than getting the 2 sum values, I want them to also be summed.
How should I go about doing this?
You can try using this in a subquery and calculate at the outer query. Ensure you use UNION ALL to evade the duplicate check
SELECT SUM(a) target_value
FROM
(SELECT
sum(target_value) a FROM table
UNION ALL
SELECT
sum(target_value) a FROM table_2) ;
You can use the WITH clause to do this:
WITH CTE AS (SELECT SUM(target_value) as FirstSum
FROM table
UNION
SELECT
SUM(target_value) as FirstSum
FROM table_2)
SELECT SUM(FirstSum) AS TotalSum FROM CTE
Please see the example below:
create table #temp (x int)
create table #temp2 (x2 int)
insert into #temp values (2)
insert into #temp values (3)
insert into #temp2 values (5)
insert into #temp2 values (6)
select t.col1,t.col2,t.col1+t.col2 as Total
from (
SELECT (select sum(x) FROM #temp) as col1,
(select sum(x2) FROM #temp2) as col2
) t

Counting repeated data

I'm trying to get maximum repeat of integer in table I tried many ways but could not make it work. The result I'm looking for is as:
"james";"108"
As this 108 when I concat of two fields loca+locb repeated two times but others did not I try below sqlfiddle link with sample table structure and the query I tried... sqlfiddle link
Query I tried is :
select * from (
select name,CONCAT(loca,locb),loca,locb
, row_number() over (partition by CONCAT(loca,locb) order by CONCAT(loca,locb) ) as att
from Table1
) tt
where att=1
please click here so you can see complete sample table and query I tried.
Edite: adding complete table structure and data:
CREATE TABLE Table1
(name varchar(50),loca int,locb int)
;
insert into Table1 values ('james',100,2);
insert into Table1 values ('james',100,3);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,7);
insert into Table1 values ('james',10,6);
insert into Table1 values ('james',0,7);
insert into Table1 values ('james',10,0);
insert into Table1 values ('james',10);
insert into Table1 values ('james',10);
and what I'm looking for is to get (james,108) as that value is repeated two time in entire data, there is repetion of (james,10) but that have null value of loca so Zero value and Null value is to be ignored only those to be considered that have value in both(loca,locb).
SQL Fiddle
select distinct on (name) *
from (
select name, loca, locb, count(*) as total
from Table1
where loca is not null and locb is not null
group by 1,2,3
) s
order by name, total desc
WITH concat AS (
-- get concat values
SELECT name,concat(loca,locb) as merged
FROM table1 t1
WHERE t1.locb NOTNULL
AND t1.loca NOTNULL
), concat_count AS (
-- calculate count for concat values
SELECT name,merged,count(*) OVER (PARTITION BY name,merged) as merged_count
FROM concat
)
SELECT cc.name,cc.merged
FROM concat_count cc
WHERE cc.merged_count = (SELECT max(merged_count) FROM concat_count)
GROUP BY cc.name,cc.merged;
SqlFiddleDemo
select name,
newvalue
from (
select name,
CONCAT(loca,locb) newvalue,
COUNT(CONCAT(loca,locb)) as total,
row_number() over (order by COUNT(CONCAT(loca,locb)) desc) as att
from Table1
where loca is not null
and locb is not null
GROUP BY name, CONCAT(loca,locb)
) tt
where att=1

How to get Distinct Records from Temp table to Sql one database table

i have temp table named "#Test" which have columns "T1", "T2", "T3" with data.
I have database table named "TestTbl" which have same columns.
I want to insert data from #Test table to TestTbl with distinct records of T1 column.
Do you have any idea how to insert distinct records in TestTbl table?
You Can Try Like this....
INSERT INTO TestTbl (T1,T2,T3) SELECT T1,T2,T3 from
(
Select Row_Number() over(Partition By T1 order By T1) as row,* from #Test
) a
where a.row=1;
INSERT INTO TestTbl (T1,T2,T3)
SELECT Distinct(T1), T2, T3 FROM #Test
EDIT After further explanation
INSERT INTO TestTbl
( T1 ,
T2 ,
T3
)
SELECT T1 ,
T2 ,
T3
FROM ( SELECT T1 ,
T2 ,
T3 ,
Row_Number() OVER ( PARTITION BY T1 ORDER BY T1) AS record
-- you need to select the relevant clause here for the order
-- do you want first or latest record?
FROM #Test
) tmp
WHERE tmp.record = 1 ;
Get distinct records
SELECT DISTINCT column_name,column_name
FROM table_name
Insert records
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...)

How to get the closest dates in Oracle sql

For example, I have 2 time tables:
T1
id time
1 18:12:02
2 18:46:57
3 17:49:44
4 12:19:24
5 11:00:01
6 17:12:45
and T2
id time
1 18:13:02
2 17:46:57
I need to get time from T1 that are the closest to time from T2. There is no relationship between this tables.
It should be something like this:
select T1.calldatetime
from T1, T2
where T1.calldatetime between
T2.calldatetime-(
select MIN(ABS(T2.calldatetime-T1.calldatetime))
from T2, T1)
and
T2.calldatetime+(
select MIN(ABS(T2.calldatetime-T1.calldatetime))
from T2, T1)
But I can't get it. Any suggestions?
You only have to use a single Cartesian join to solve you problem unlike the other solutions, which use multiple. I assume time is stored as a VARCHAR2. If it is stored as a date then you can remove the TO_DATE functions. If it is stored as a date (I would highly recommend this), you will have to remove the date portions
I've made it slightly verbose so it's obvious what's going on.
select *
from ( select id, tm
, rank() over ( partition by t2id order by difference asc ) as rnk
from ( select t1.*, t2.id as t2id
, abs( to_date(t1.tm, 'hh24:mi:ss')
- to_date(t2.tm, 'hh24:mi:ss')) as difference
from t1
cross join t2
) a
)
where rnk = 1
Basically, this works out the absolute difference between every time in T1 and T2 then picks the smallest difference by T2 ID; returning the data from T1.
Here it is in SQL Fiddle format.
The less pretty (but shorter) format is:
select *
from ( select t1.*
, rank() over ( partition by t2.id
order by abs(to_date(t1.tm, 'hh24:mi:ss')
- to_date(t2.tm, 'hh24:mi:ss'))
) as rnk
from t1
cross join t2
) a
where rnk = 1
I believe this is the query you are looking for:
CREATE TABLE t1(id INTEGER, time DATE);
CREATE TABLE t2(id INTEGER, time DATE);
INSERT INTO t1 VALUES (1, TO_DATE ('18:12:02', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (2, TO_DATE ('18:46:57', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (3, TO_DATE ('17:49:44', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (4, TO_DATE ('12:19:24', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (5, TO_DATE ('11:00:01', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (6, TO_DATE ('17:12:45', 'HH24:MI:SS'));
INSERT INTO t2 VALUES (1, TO_DATE ('18:13:02', 'HH24:MI:SS'));
INSERT INTO t2 VALUES (2, TO_DATE ('17:46:57', 'HH24:MI:SS'));
SELECT t1.*, t2.*
FROM t1, t2,
( SELECT t2.id, MIN (ABS (t2.time - t1.time)) diff
FROM t1, t2
GROUP BY t2.id) b
WHERE ABS (t2.time - t1.time) = b.diff;
Make sure that the time columns have the same date part, because the t2.time - t1.time part won't work otherwise.
EDIT: Thanks for the accept, but Ben's answer below is better. It uses Oracle analytic functions and will perform much better.
This one here selects that row(s) from T1, which has/have the smallest distance to any in T2:
select T1.id, T1.calldatetime from T1, T2
where ABS(T2.calldatetime-T1.calldatetime)
=( select MIN(ABS(T2.calldatetime-T1.calldatetime))from T1, T2);
(tested it with mysql, hope you dont get an ORA from that)
Edit: according to the last comment, it should be like that:
drop table t1;
drop table t2;
create table t1(id int, t time);
create table t2(id int, t time);
insert into t1 values (1, '18:12:02');
insert into t1 values (2, '18:46:57');
insert into t1 values (3, '17:49:44');
insert into t1 values (4, '12:19:24');
insert into t1 values (5, '11:00:01');
insert into t1 values (6, '17:12:45');
insert into t2 values (1, '18:13:02');
insert into t2 values (2, '17:46:57');
select ot2.id, ot2.t, ot1.id, ot1.t from t2 ot2, t1 ot1
where ABS(ot2.t-ot1.t)=
(select min(abs(t2.t-t1.t)) from t1, t2 where t2.id=ot2.id)
Produces:
id t id t
1 18:13:02 1 18:12:02
2 17:46:57 3 17:49:44
Another one way of using analytic functions.
May be strange :)
select id, time,
case
when to_date(time, 'hh24:mi:ss') - to_date(lag_time, 'hh24:mi:ss') < to_date(lead_time, 'hh24:mi:ss') - to_date(time, 'hh24:mi:ss')
then lag_time
else lead_time
end closest_time
from (
select id, tbl,
LAG(time, 1, null) OVER (ORDER BY time) lag_time,
time,
LEAD(time, 1, null) OVER (ORDER BY time) lead_time
from
(
select id, time, 1 tbl from t1
union all
select id, time, 2 tbl from t2
)
)
where tbl = 2
To SQLFiddle... and beyond!
Try this query its little lengthy, I will try to optimize it
select * from t1
where id in (
select id1 from
(select id1,id2,
rank() over (partition by id2 order by diff) rnk
from
(select distinct t1.id id1,t2.id id2,
round(min(abs(to_date(t1.time,'HH24:MI:SS') - to_date(t2.time,'HH24:MI:SS'))),2) diff
from
t1,t2
group by t1.id,t2.id) )
where rnk = 1);