Related
USE mydb;
create table #payments
( id int, contract_ID varchar(20), payment_number int, payment_status varchar(20));
insert #payments (id, contract_id, payment_number, payment_status)
values
(1, 'contract1', 1, 'Processed'),
(2, 'contract1', 2, 'Received'),
(3, 'contract2', 1, 'Processed'),
(4, 'contract2', 2, 'Approved'),
(5, 'contract1', 3, 'Approved'),
(6, 'contract2', 3, 'Processed');
Is it correct that the above SQL script creates a table named #payments in the database 'mydb'?
When I run the above for the second time, SSMS says
There is already an object named '#payments' in the database.
But why can't I find the table in the output of
USE mydb;
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS
GROUP BY TABLE_NAME
?
Thanks
Is it correct that the above SQL script creates a table named #payments in the database 'mydb'?
No, that's not correct.
# indicates a temporary table, it's created in tempdb
select Object_Id('tempdb.dbo.#payments');
select *
from tempdb.sys.tables
where name like '#payments%';
You'll see it exists with a negative object ID and name appended with a long "uniquifier".
Likewise prefixing any object name with # indicates it is a temporary object and will be managed for you in tempdb. Objects created with a single hash prefix are scoped to your own session, a double hash indicates they are global and visible to all sessions. Temporary objects are automatically dropped when they go out of scope, ie, are no longer referenced.
IN MSSQL when we create temp table we use #
use mydb;
create table #payments
( id int, contract_ID varchar(20), payment_number int, payment_status varchar(20));
insert into #payments (id, contract_id, payment_number, payment_status)
values
(1, 'contract1', 1, 'Processed'),
(2, 'contract1', 2, 'Received'),
(3, 'contract2', 1, 'Processed'),
(4, 'contract2', 2, 'Approved'),
(5, 'contract1', 3, 'Approved'),
(6, 'contract2', 3, 'Processed');
select * from #payments
You can find table by using below query:
select * from tempdb..sysobjects
I have a table that stores data in a one minute timestamp from each other and I'd like to create a select command, that would fetch data from the :59 minute mark from each hour of a requested period, for example from 01.01.2020 to 01.02.2020.
How could I do this? I attach a sample of data from that table, to which the select command will refer to:
I think you're looking for something like this. In plain language the code says "For the range of start date to end date, select the hourly summary statistics for the test table without skipping any hours."
Table
drop table if exists test_table;
go
create table test_table(
ID int primary key not null,
date_dt datetime,
INP3D decimal(4, 3),
ID_device varchar(20));
Data
insert test_table(ID, date_dt, INP3D, ID_device) values
(1, '2020-08-21 13:44:34.590', 3.631, 'A1'),
(2, '2020-08-21 13:44:34.590', 1.269, 'A1'),
(3, '2020-08-21 13:44:34.590', 0.131, 'A1'),
(4, '2020-08-21 13:44:34.590', 8.169, 'A1');
--select * from test_table;
insert test_table(ID, date_dt, INP3D, ID_device) values
(5, '2020-08-21 11:44:34.590', 3.631, 'A1'),
(6, '2020-08-21 02:44:34.590', 1.269, 'A1'),
(7, '2020-08-22 11:44:34.590', 0.131, 'A1'),
(8, '2020-08-22 01:44:34.590', 8.169, 'A1');
Query
declare
#start_dt datetime='2020-08-21',
#end_dt datetime='2020-08-22';
;with
hours_cte as (
select hours_n
from
(VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),
(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24)) v(hours_n)),
days_cte as (
select dateadd(d, hours_n-1, #start_dt) calc_day from hours_cte where hours_n<=datediff(d, #start_dt, #end_dt)+1)
select
dc.calc_day,
hc.hours_n,
count(*) row_count,
isnull(avg(INP3D), 0) inp3d_avg,
isnull(sum(INP3D+0000.000),0) inp3d_sum
from days_cte dc
cross join hours_cte hc
left join test_table t on t.date_dt between dateadd(hour, (hours_n-1), dc.calc_day)
and dateadd(hour, (hours_n), dc.calc_day)
group by
dc.calc_day,
hc.hours_n
order by
1,2;
This?
SELECT * FROM table WHERE DATEPART(MINUTE, 'your_datetime') = '59'
Datepart
Suppose I have a table
Declare #table table
(
id int,
month_col varchar(10),
present_col bit,
absent_col bit,
leave_col bit
);
insert into #table
values (1, 'Jan', 1, 0, 0),
(2, 'Jan', 1, 0, 0),
(3, 'Jan', 0, 1, 0),
(4, 'Jan', 1, 0, 0),
(5, 'Jan', 0, 1, 0),
(6, 'Jan', 1, 0, 0),
(7, 'Jan', 1, 0, 0);
While updating some rows, I need to check all previous rows leave col to take decision for current row, this need to be done for all rows, I had achieve this with while loop like this
while(for all rows)
begin
update #table
set l = mylogic_function((select count(leave_col)
from #table
where id<currentrow.ID))
where id = currentrow.ID
end
but I want to do this logic by using a CTE.
I don't know what your function does so, for my example I created a function that takes an input and returns a 1 when that number is divisible by three. Obviously you can change the logic to what you need.
CREATE FUNCTION dbo.someFunction(#x INT) RETURNS BIT AS BEGIN RETURN (SIGN(#x%3)-1) END;
It's good that you don't want to do this using a loop BUT a solution that uses a recursive CTE (if that's what you are looking for) will likely perform poorly and will be overly complicated for what you are trying to do. Set-based is always the way to go.
To get a count of all rows before your "current" row you could simply use this syntax:
COUNT(t.leave_col) OVER (ORDER BY t.Id)
This will return the same thing as above but will be faster:
ROW_NUMBER() OVER (ORDER BY t.Id)
This query will do what you're looking for and will be faster than using a loop or recursive CTE:
-- Sample data
Declare #table table(id int,month_col varchar(10),present_col bit, absent_col bit,leave_col bit);
insert into #table values
(1,'Jan',1,0,0),
(5,'Jan',1,0,0),
(13,'Jan',0,1,0),
(14,'Jan',1,0,0),
(25,'Jan',0,1,0),
(26,'Jan',1,0,0),
(37,'Jan',1,0,0);
-- Solution
WITH Prep(leave_col_count, leave_col) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY t.Id), t.leave_col
FROM #table AS t
)
UPDATE Prep
SET leave_col = dbo.someFunction(Prep.leave_col_count)
FROM Prep;
I have a table, in the table i have for example 4 columns
(ID(for example 12 different ID repeating for 10000 rows but then +26 added for the next 10000 rows),
Date (ordered by this -can't be changed-),
Error(-1,0,1),
ItemName,
What should i do if i want to make my query warn me if there were 3 error for the same ID right after each other
(It's not sure that the rows are actually right after each other, because the whole table ordered by Date, so ID 1 can be in the first row and then the 13th and then the 25th for example) ?
According to what I understand, you need Items which has 3 errors and it is in consecutive lines on order by date.
Please refer my code and this support sql server
/*create table*/
CREATE TABLE YourTable( PK_Id int NOT NULL IDENTITY(1,1) primary key,
ID int NOT NULL,
CreatedDate datetime NOT NULL,
Error int NOT NULL,
ItemName nvarchar(100) NULL);
/*sample data 1*/
INSERT INTO YourTable VALUES (1, '2018-10-13 10:10:10', -1, 'Item-1'),
(2, '2018-10-13 10:10:15', -1, 'Item-2'),
(3, '2018-10-13 10:10:17', -1, 'Item-3'),
(4, '2018-10-13 10:10:17', -1, 'Item-4'),
(1, '2018-10-14 10:10:10', 0, 'Item-1'),
(2, '2018-10-14 10:10:15', 0, 'Item-2'),
(3, '2018-10-14 10:10:17', 0, 'Item-3'),
(4, '2018-10-14 10:10:17', 0, 'Item-4'),
(1, '2018-10-15 10:10:10', 1, 'Item-1'),
(2, '2018-10-15 10:10:15', 1, 'Item-2'),
(3, '2018-10-15 10:10:17', 1, 'Item-3'),
(4, '2018-10-15 10:10:17', 1, 'Item-4')
/*sample data 2*/
INSERT INTO YourTable VALUES (5, '2018-10-16 10:10:10', -1, 'Item-5'),
(5, '2018-10-16 10:10:15', 0, 'Item-5'),
(5, '2018-10-16 10:10:17', 1, 'Item-5')
SELECT Id, ItemName
FROM YourTable
GROUP BY Id, ItemName
HAVING COUNT(Error) = 3 /*check number of errors*/
AND SUM(Error) = 0 /*check all 3 errors*/
AND SUM(PK_Id) = MIN(PK_Id) * 3 + 3 /*check right after each error*/
This should get you started; use the LAG() function in SQL Server 2012+ to determine the value in the previous row, and the row before that (there may be a way to do this in one pass rather than two, like I'm doing). This will return the last row in a sequence of three errors (assuming -1 is the error code).
USE tempdb;
CREATE TABLE Logs (ID int, Dt datetime, error int, itemname varchar(20))
CREATE CLUSTERED INDEX cx ON LOGS (dt)
INSERT INTO LOGS
VALUES (1, '20180101', -1, 'error'),
(1, '20180102', -1, 'error'),
(1, '20180103', -1, 'error'),
(1, '20180104', 0, 'no error'),
(2, '20180102', -1, 'error'),
(2, '20180103', -1, 'error'),
(2, '20180104', 0, 'no error'),
(2, '20180105', -1, 'error')
; with c AS (
SELECT *
, LAG(error, 1,0) OVER (PARTITION BY ID ORDER BY Dt) prv1
, LAG(error, 2,0) OVER (PARTITION BY ID ORDER BY Dt) prv2
FROM Logs
)
SELECT *
FROM c
WHERE error = prv1 and error = prv2
AND error = -1
DROP TABLE Logs
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a table like this :
I want to insert into detail_salary_table with Insert into Select statement.
I can insert the salary_component item "Salary" with this code
INSERT INTO detail_salary_table (date_work, id_emp, salary_component, nominal)
SELECT
date_work, id_emp, 'Salary',
IIF(DATEDIFF(minute, start_work, finish_work) > 480, 10000, round(convert(float(53), datediff(minute, start_work, finish_work)) / 480, 1) * 10000)
FROM
attendance_table
How to insert the salary_component item "OverTime" with T-SQL like the image?
If I use VB.NET, I can do it with if and loop statement.
Note :
480 is fix. 10.000 is fix.
overtime = finish_work - start_work - 480. It take nominal from overtime_rate_table where the value near to time_in_minutes
the increment of nominal in overtime_rate_table is not measured. (so, i cannot use * 1000) (example is measured)
The SQL code to create the tables and sample data:
create table employee_table
(
id_emp int primary key,
name_emp varchar(200)
);
GO
create table attendance_table
(
id_data int primary key identity(1,1),
date_work date,
id_emp int,
start_work datetime,
finish_work datetime
);
GO
create table overtime_rate_table
(
id_data int,
time_in_minutes int,
nominal money
);
GO
create table detail_salary_table
(
id_data int primary key identity(1,1),
date_work date,
id_emp int,
salary_component varchar(100),
nominal money
);
GO
insert into employee_table
values (1, 'Emp A'), (2, 'Emp B'), (3, 'Emp C'), (4, 'Emp D'), (5, 'Emp E');
GO
insert into attendance_table (date_work, id_emp, start_work, finish_work)
values
('2017-02-01',1,'2017-02-01 08:00','2017-02-01 16:52'),
('2017-02-01',2,'2017-02-01 07:45','2017-02-01 16:48'),
('2017-02-01',3,'2017-02-01 08:02','2017-02-01 12:05'),
('2017-02-01',4,'2017-02-01 07:56','2017-02-01 16:49'),
('2017-02-01',5,'2017-02-01 07:30','2017-02-01 18:05'),
('2017-02-02',1,'2017-02-02 07:52','2017-02-02 16:23'),
('2017-02-02',2,'2017-02-02 07:19','2017-02-02 18:56'),
('2017-02-02',3,'2017-02-02 07:55','2017-02-02 18:23'),
('2017-02-02',4,'2017-02-02 08:01','2017-02-02 16:01'),
('2017-02-02',5,'2017-02-02 07:31','2017-02-02 16:49'),
('2017-02-03',1,'2017-02-03 07:52','2017-02-03 17:44'),
('2017-02-03',2,'2017-02-03 07:41','2017-02-03 17:23'),
('2017-02-03',3,'2017-02-03 07:06','2017-02-03 17:56'),
('2017-02-03',4,'2017-02-03 07:56','2017-02-03 19:00'),
('2017-02-03',5,'2017-02-03 07:45','2017-02-03 18:56');
GO
insert into overtime_rate_table
values (1, 15, 1000), (2, 30, 2000), (3, 45, 3000),
(4, 60, 4000), (5, 75, 5000), (6, 90, 6000),
(7, 105, 7000), (8, 120, 8000), (9, 135, 9000),
(10, 150, 10000), (11, 165, 11000), (12, 180, 12000),
(13, 195, 13000), (14, 210, 14000), (15, 225, 15000);
GO
INSERT INTO detail_salary_table
(date_work,
id_emp,
salary_component,
nominal
)
SELECT date_work,
id_emp,
'OverTime',
ISNULL(o.Nominal, 0)
FROM attendance_table a
LEFT JOIN overtime_rate_table o ON CONVERT( INT, DATEDIFF(minute, a.start_work, a.finish_work) - 480) / 15 * 15 = o.time_in_minutes;