Why can't I find a table in a database? - sql-server

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

Related

Getting duplicate rows in SQL Server

The screenshot contains of 3 tables all connected with other
The second screenshot shows the SQL query and the result obtained:
Query:
SELECT DISTINCT
t.topic_id
, t.topic_name
, t.topic_cover
, t.topic_viewers
, t1.subscribe_id
FROM
tbltopic t
INNER JOIN
tblsubject_grade tg ON (t.subject_garde_id = tg.subject_garde_id)
INNER JOIN
tblsubcription t1 ON (tg.subject_garde_id = t1.subject_garde_id)
The real issue is you have multiple JOIN conditions across a couple of tables
Check this image:
You ll see that table tblsubject_grade JOINS to BOTH the other tables.
Youre query should be:
if OBJECT_ID('tempdb..#topic') IS NOT NULL DROP TABLE #topic
if OBJECT_ID('tempdb..#subjGrade') IS NOT NULL DROP TABLE #subjGrade;
if OBJECT_ID('tempdb..#subscription') IS NOT NULL DROP TABLE #subscription;
CREATE TABLE #topic (topic_id int, topic_name varchar(20), topic_cover varchar(20), topic_viewers int, teacher_id int, subject_garde_id int);
CREATE TABLE #subjGrade (subject_garde_id INT, grade_id INT, subject_id INT);
CREATE TABLE #subscription (subscribe_id INT, sub_status INT, sub_date date, student_id INT, archive_status INT, teacher_id int, subject_garde_id int);
INSERT INTO #topic (topic_id, topic_name, topic_cover, topic_viewers, teacher_id, subject_garde_id)
VALUES
(4, 'numbers', 'somestring', 0,2,1),
(6, 'shapes', 'somestring', 0,9,1),
(7, 'story time', 'somestring', 0, 2, 5)
INSERT INTO #subjGrade (subject_garde_id , grade_id , subject_id)
VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 2, 1),
(5, 2, 2),
(6, 2, 3),
(7, 2, 4),
(8, 3, 1)
INSERT INTO #subscription (subscribe_id, sub_status, sub_date, student_id, archive_status , teacher_id , subject_garde_id)
VALUES
(2, 1, '9-7-2021', 1,0,9,1),
(3, 1, '9-7-2021', 1,0,2,1)
SELECT
t.topic_id
, t.topic_name
, t.topic_cover
, t.topic_viewers
, t1.subscribe_id
FROM #topic t
INNER JOIN #subjGrade tg ON t.subject_garde_id = tg.subject_garde_id
INNER JOIN #subscription t1 ON
tg.subject_garde_id = t1.subject_garde_id
AND t1.subject_garde_id = t.subject_garde_id
AND t.teacher_id = t1.teacher_id

How to write query with cast and switch functions in SQL Server?

I have to convert an int column to a text column and replace the integer values within that column.
For example I have a column status that can contain values like 0, 1, 2, 3, 4, 5, 6, 7.
For '0' I have to replace the value with "New", for '1' with "Identified" and so on.
For this scenario how to write a SQL query?
Personally, I'd go with a mapping table, but another option is CHOOSE() or even the traditional CASE
Note the +1 in the CHOOSE option ... 0 is not a valid option and would return NULL
Example
Declare #YourTable Table ([Status] int)
Insert Into #YourTable Values
(0),(1),(2),(3)
Select *
,ViaCHOOSE = choose([Status]+1,'New','Identified','Some Other','...')
,ViaCASE = case [Status]
when 0 then 'New'
when 1 then 'Identified'
when 2 then 'Some Other'
else null -- or 'Undefined'
end
From #YourTable
Results
Status ViaCHOOSE ViaCASE
0 New New
1 Identified Identified
2 Some Other Some Other
3 ... ...
You could create a (temporary) table with that mapping.
create table XYMapping (number int, text varchar(max));
INSERT INTO XYMapping (number, text) VALUES (1, 'New'), (2, 'Identified'); -- ...
Insert all values and then join them.
Steps to follow to convert int column to text and replace the existing values.
Alter the table. Since INT converts to text implicitly NOT NULL is able to be maintained
Exec UPDATE statement using conversion table specified using VALUES table value constructor
Something like this
drop table if exists #samples;
go
create table #samples (
id int not null,
stat varchar(10) not null);
insert #samples(id, stat) values
(10, 'Start'),
(1, 'Start'),
(1, 'Failed'),
(2, 'Start'),
(3, 'Start'),
(3, 'Failed'),
(4, 'Start'),
(4, 'Failed'),
(4, 'Start'),
(4, 'Failed');
/* step 1: alter the table (and implicitly convert) */
alter table #samples
alter column
id varchar(20) not null;
/* step 2: update based on conversion table */
update s
set id=v.new_str
from #samples s
join
(values ('1', 'New'),
('2', 'Identified'),
('3', 'Identified'),
('4', 'Identified'),
('10', 'Other')) v(old_int, new_str) on s.id=v.old_int;
select * from #samples;
id stat
Other Start
New Start
New Failed
Identified Start
Identified Start
Identified Failed
Identified Start
Identified Failed
Identified Start
Identified Failed

SQL Server : select data from table based on certain timestamp

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

Is it possible to use where in with if not exist select statement in SQL Server?

I would like to update table comparing with multiple values.
However, the command completed successfully without insert data if one of them in condition satisfies, I would like to insert one another value if mid is not in the table.
Is it possible to extend the SQL query more than as follows?
IF (NOT EXISTS (SELECT * FROM membership WHERE mid IN (513, 761, ...)))
INSERT INTO membership (id, uId, rId, gId, assignedBy .... )
VALUES (1, 226, 5, 1, 5, 3),
(1, 227, 7, 6, 1, 3)
...
Thanks in advance.
Your question is not clear but let me pose this answer:
If you want to insert records that don't exist based on a key columns, use this pattern:
-- First set up a virtual table called SRC that contains our manual values
-- This is called a CTE (Common Table Expression)
WITH SRC AS
(
SELECT * FROM
(
VALUES
(1, 226, 5, 1, 5, 3),
(1, 227, 7, 6, 1, 3)
) as T (id, uId, rId, gId, assignedBy, mid)
)
-- select only those values that don't exist in the target and insert them
INSERT INTO membership (id, uId, rId, gId, assignedBy,mid)
SELECT id, uId, rId, gId, assignedBy,mid FROM SRC
WHERE NOT EXISTS (
SELECT *
FROM membership TGT WHERE TGT.mid = SRC.mid)
Granted the MERGE version of this would probably be a but simpler. You could also rewrite this in many other ways - you could exclude already existing rows in the CTE

join many rows into one xml column

I have two tables like this:
and
The first generated table lists all the actors/directors/other and the second table lists all the movies. What I need to do is fit all the Person_ID and Name into one column in the second table, ideally through a join and XML conversion. I know how to convert a whole table to an XML, but I am not sure how to do it to a dozen rows on the fly, is iteration the way? Any ideas?
If you use FOR XML PATH('') it eliminates the root tags. If you do not specify a column alias, it will just output the value. So you can create a string of values in a sub-query as one of the column values. Something like this should get you started:
create table #Cast (FilmID int, Person_ID int, PersonName varchar(20))
create table #Films (FilmID int , FilmName varchar(20))
insert into #Cast values (1, 1, 'bob')
insert into #Cast values (1, 2, 'tom')
insert into #Cast values (2, 3, 'sam')
insert into #Cast values (2, 4, 'ray')
insert into #Films values (1, 'Flowers for Charlie')
insert into #Films values (2, 'Batman')
SELECT #Films.*,
SUBSTRING(
(SELECT ( ',' + convert(varchar(10),Person_ID) + ',' + PersonName)
FROM #Cast
WHERE #Films.FilmID = #Cast.FilmID
ORDER BY #Films.FilmID, #Cast.FilmID
FOR XML PATH('')
), 2, 8000) CastList
FROM #Films

Resources