Union on two tables based on a specific column - sql-server

I have two tables which have many records , both table have few records where the id is same , I want to have unique group of rows where I have unique id from one particular table incase there are two same id in table
for example
In the above snippet we have empid 1 on both table so , I want all the records such that If there are common empid in both table then value for the common empid the value should be used from Dummy_tab_2 table .
Desired O/P
code to replicate
CREATE TABLE Dummy_tab_1
(
empid int,
Month1 int,
Month2 int,
);
INSERT INTO Dummy_tab_1
VALUES (1, 100, 200), (5,15, 20), (6, 20, 30);
CREATE TABLE Dummy_tab_2
(
empid int,
Month1 int,
Month2 int,
);
INSERT INTO Dummy_tab_2
VALUES (1, 10, 20), (2,15, 20), (3, 20, 30);
I tried this but not sure how to remove the emp id which is not desired
SELECT *
FROM Dummy_tab_2
UNION
SELECT *
FROM Dummy_tab_1
and o/p which I got is this

Using:
SELECT * FROM Dummy_tab_1 WHERE empid NOT IN (SELECT empid FROM Dummy_tab_2)
UNION ALL
SELECT * FROM Dummy_tab_2;
db<>fiddle demo

Using your data examples and what looks like your desired results this should work:
CREATE TABLE Dummy_tab_1
(
empid int,
Month1 int,
Month2 int,
);
INSERT INTO Dummy_tab_1
VALUES (1, 100, 200), (5,15, 20), (6, 20, 30);
CREATE TABLE Dummy_tab_2
(
empid int,
Month1 int,
Month2 int,
);
INSERT INTO Dummy_tab_2
VALUES (1, 10, 20), (2,15, 20), (3, 20, 30);
SELECT COALESCE(DT1.empid, DT2.EmpID) AS EmpID, CASE WHEN DT2.empid IS NOT NULL THEN DT2.Month1 ELSE DT1.Month1 END AS Month1,
CASE WHEN DT2.empid IS NOT NULL THEN DT2.Month2 ELSE DT1.Month2 END AS Month2
FROM Dummy_tab_1 DT1
FULL JOIN Dummy_tab_2 DT2 ON DT1.empid = DT2.empid
ORDER BY COALESCE(DT1.empid, DT2.EmpID)

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

Get max value from table and group by with column having comma separated value with different order or having more values

I am having a table like this along with data
CREATE TABLE temp (
`name` varchar(20),
`ids` varchar(20),
`value1` int,
`value2` int
);
INSERT INTO temp(`name`,`ids`, `value1`, `value2`) values
('A', '1,2', 10, 11),
('A', '2,1', 12, 100),
('A', '1,2,3', 20, 1),
('B', '6', 30, 10)
I need to get the max value by Name along with ids
I am using the following query to get the max value.
select name, ids, max(value1) as value1, max(value2) as value2
from temp
group by name,ids
The question has been tagged as Sybase ASE, but the 'create table and 'insert' commands are invalid in ASE so not sure if this is an issue of an incorrect tag or the wrong 'create table' and 'insert' commands ... so, assuming this is for a Sybase ASE database:
I'm assuming the desired output is to display those rows where value = max(value).
First we'll setup our test case:
create table mytab
(name varchar(20)
,ids varchar(20)
,value int)
go
insert into mytab (name,ids,value) values ('A', '1,2' , 10)
insert into mytab (name,ids,value) values ('A', '2,1' , 12)
insert into mytab (name,ids,value) values ('A', '1,2,3', 20)
insert into mytab (name,ids,value) values ('B', '6' , 30)
go
Here's one possible solution:
select t.name, t.ids, t.value
from mytab t
join (select name,max(value) as maxvalue from mytab group by name) dt
on t.name = dt.name
and t.value = dt.maxvalue
order by t.name
go
name ids value
-------------------- -------------------- -----------
A 1,2,3 20
B 6 30
The subquery/derived-table gives us the max(value) for each unique name. The main query then joins these name/max(value) pairs back to the main table to give us the desired rows (ie, where value = max(value)).
Tested on ASE 15.7 SP138.

How check if specific record exist in table or not

I have a table in which I have multiple dates stored which are the attendance dates of employee
CREATE TABLE Attendance
(
EmpCode INT,
AttendanceDate DATETIME
)
INSERT INTO Attendance VALUES (24, '2018-12-01');
INSERT INTO Attendance VALUES (24, '2018-12-02');
INSERT INTO Attendance VALUES (24, '2018-12-03');
INSERT INTO Attendance VALUES (24, '2018-12-04');
INSERT INTO Attendance VALUES (24, '2018-12-06');
Now as there is not date saved for this employee on 5th Dec it should show Absent in that case.
SELECT * FROM Attendance
It will give missed date for that emp from table if you want to insert you can insert by using existing code
CREATE TABLE #Attendance
(
EmpCode INT,
AttendanceDate DATETIME
)
INSERT INTO #Attendance VALUES (24, '2018-12-01');
INSERT INTO #Attendance VALUES (24, '2018-12-02');
INSERT INTO #Attendance VALUES (24, '2018-12-03');
INSERT INTO #Attendance VALUES (24, '2018-12-04');
INSERT INTO #Attendance VALUES (24, '2018-12-06');
select * from #Attendance
;WITH CTE AS
(
SELECT CONVERT(DATE,'2018-12-01') AS DATE1
UNION ALL
SELECT DATEADD(DD,1,DATE1) FROM CTE WHERE DATE1<'2018-12-06'
)
--insert into #Attendance(EmpCode,AttendanceDate)
SELECT DATE1 MISSING_ONE,'a' FROM CTE
EXCEPT
SELECT AttendanceDate,'a' FROM #Attendance
option(maxrecursion 0)

Query where date = '2016/01/02' not working?

SQL FIDDLE DEMO HERE
I have this structure of table:
CREATE TABLE Department
(
[IdDepartment] int,
[Name] varchar(23),
[IdUser] int,
[CreateDate] datetime
);
INSERT INTO Department ([IdDepartment], [Name], [IdUser], [CreateDate])
VALUES
(1, 'Sales', 3, '2016-01-15 17:00:00.000'),
(2, 'Finance', null, '2016-01-13 18:00:00.000' ),
(3, 'Accounting' , 5, '2016-03-21 22:00:00.000'),
(4, 'IT' ,3, '2016-03-21 17:00:00.000'),
(5, 'Secretary',null, '2016-03-21 17:00:00.000'),
(6, 'Sport',3, '2016-02-20 16:00:00.000');
I want to run this query:
select Name
from Department
where CreateDate = '2016-03-21'
This returns 0 rows as a result.
I think it is because the date in the table structure is a datetime but I try to do this and neither works for me:
select Name
from Department
where CreateDate like '%2016-03-21%'
The result should be this:
Name
-----
Accounting
IT
Secretary
How can I get this result?
I hope I explained clearly, thanks
You are comparing a DATETIME value against a pure DATE. You must be aware, that a DATETIME includes a time
2016-03-21 11:00:00 is NOT equal to 2016-03-21
You might compare like this
CAST(YourDate AS DATE)=CAST('2016-03-21' AS DATE)
Hint: As one tiny exception! - CAST(someCol AS DATE) actually is sargable, but it's worth to mention, that it still is not the best idea to do: dba.stackexchange.com/a/34052/70663
or you could try a BETWEEN
YourDate BETWEEN {d'2016-03-21'} AND {ts'2016-03-21 23:59:59'}
or - which is the most prefered in most cases
YourDate >= {d'2016-03-21'} AND YourDate < {d'2016-03-22'}
Avoid manipulations to the column value due to sargability
Better avoid date literals... If you have to, you might read this
Use CAST method to compare date only not time
SELECT * FROM Department
WHERE CAST(CreateDate AS DATE) ='2016-03-21'
Fully agree with #Shnugo
DECLARE #Department TABLE (
IdDepartment INT,
Name VARCHAR(23),
IdUser INT,
CreateDate DATETIME
);
INSERT INTO #Department
VALUES
(1, 'Sales', 3, '2016-01-15 17:00:00'),
(2, 'Finance', NULL, '2016-01-13 18:00:00'),
(3, 'Accounting', 5, '2016-03-21 22:00:00'),
(4, 'IT', 3, '2016-03-21 17:00:00'),
(5, 'Secretary', NULL, '2016-03-21 17:00:00'),
(6, 'Sport', 3, '2016-02-20 16:00:00')
DECLARE #Date DATETIME = '20160321' -- ISO format
SELECT Name
FROM #Department
WHERE CreateDate >= #Date
AND CreateDate < DATEADD(DAY, 1, #Date)

can we implement innerjoin in the following sql query

These are my tables:
CREATE TABLE forgerock (id INT, [date] DATETIME, empcode INT,[file] VARCHAR);
INSERT INTO forgerock
VALUES
(1, '2015-12-31 01:20:02', 56, 'abc1'),
(2, '2016-01-01 01:20:02', 58, 'abc2'),
(3, '2016-01-02 01:20:02', 46, 'abc3'),
(4, '2016-01-03 01:20:02', 16, 'abc4'),
(5, '2016-01-04 01:20:02', 36, 'abc5');
CREATE TABLE forge (empcode INT, [user_name] VARCHAR);
INSERT INTO forge
VALUES
(56, 'ram'),
(58, 'ram1'),
(46, 'ram2'),
(16, 'ram3'),
(36, 'ram4');
I am trying to print the file name and user_name from the tables with respect to current date and the day before the current date.
I tried the query:
ResultSet resultset = statement.executeQuery("select file from forgerock where '"+date+"' >= CURRENT_DATE('"+date+"', INTERVAL 1 DAY);") ;
but I got the exception:
Incorrect syntax near the keyword 'CURRENT_DATE'.
IF OBJECT_ID('dbo.forgerock', 'U') IS NOT NULL
DROP TABLE dbo.forgerock
CREATE TABLE dbo.forgerock (id INT PRIMARY KEY, [date] DATETIME, empcode INT,[file] VARCHAR(10));
INSERT INTO dbo.forgerock
VALUES
(1, '2015-12-31 01:20:02', 56, 'abc1'),
(2, '2016-01-01 01:20:02', 58, 'abc2'),
(3, '2016-01-02 01:20:02', 46, 'abc3'),
(4, '2016-01-03 01:20:02', 16, 'abc4'),
(5, '2016-01-04 01:20:02', 36, 'abc5');
IF OBJECT_ID('dbo.forge', 'U') IS NOT NULL
DROP TABLE dbo.forge
CREATE TABLE dbo.forge (empcode INT PRIMARY KEY, [user_name] VARCHAR(10));
INSERT INTO dbo.forge
VALUES (56, 'ram'),(58, 'ram1'),(46, 'ram2'),(16, 'ram3'),(36, 'ram4')
DECLARE #dt DATETIME = FLOOR(CAST(GETDATE() AS FLOAT))
SELECT *
FROM dbo.forge
WHERE empcode IN (
SELECT f.empcode
FROM dbo.forgerock f
WHERE f.[date] BETWEEN DATEADD(DAY, -1, #dt) AND #dt
)
output -
empcode user_name
----------- ----------
16 ram3
SELECT fr.file, f.user_name
FROM forgerock fr inner join forge f on fr.empcode = f.empcode
WHERE fr.date >= DATE_ADD(NOW(), INTERVAL -1 DAY)
You can use datediff to get the difference between two dates.
Try this :
ResultSet resultset = statement.executeQuery("select file from forgerock where DATEDIFF(day, GETDATE(), '" + date + "') >= 1") ;
To test the query use this one :
SELECT * FROM forgerock WHERE DATEDIFF(day, GETDATE(), #date) >= 1;
Just replace the #date with the value you want, for example '2016-01-02'
Use this filter:
SELECT [file]
FROM forgerock
WHERE [date] >= DATEADD(DAY, DATEDIFF(DAY,0,GETDATE()-1),0)
The DATEADD expression above will always return 12:00am yesterday morning, allowing your query to only return records from yesterday or today.
Bonus Tip: avoid using reserved keywords (such as file and date) as column or table names.
Since am using ms sql the code should be the following way
SELECT fr.file, f.user_name FROM forgerock fr inner join forge f on fr.empcode = f.empcodewhere [date] >= DATEADD(DAY, DATEDIFF(DAY,0,GETDATE()-1),0)
which will result in printing the two tables file from forgerock and user_name from forge
You have to try following query:-
SELECT fr.file, f.user_name
FROM forgerock fr inner join forge f on fr.empcode = f.empcode
AND `date' >= (DATE_ADD(`date`, INTERVAL 1 day))

Resources