Trying to use CTE to replace codes with names - sql

Expecting to get names instead of codes which is highlighted in yellow.
Employee Table
CREATE TABLE [dbo].[_Employees](
[Name] [nvarchar](50) NULL,
[Code] [nvarchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[_Employees] ([Name], [Code]) VALUES (N'A', N'1')
GO
INSERT [dbo].[_Employees] ([Name], [Code]) VALUES (N'B', N'2')
GO
INSERT [dbo].[_Employees] ([Name], [Code]) VALUES (N'C', N'3')
GO
Data Table
CREATE TABLE [dbo].[_Details](
[Department] [nvarchar](50) NULL,
[Zone] [nvarchar](50) NULL,
[Place] [nvarchar](50) NULL,
[City] [nvarchar](50) NULL,
[L1] [nchar](10) NULL,
[L2] [nchar](10) NULL,
[L3] [nchar](10) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[_Details] ([Department], [Zone], [Place], [City], [L1], [L2], [L3]) VALUES (N'Department1', N'Zone1', N'Place1', N'City1', N'1 ', N'2 ', N'3 ')
GO
INSERT [dbo].[_Details] ([Department], [Zone], [Place], [City], [L1], [L2], [L3]) VALUES (N'Department2', N'Zone2', N'Place2', N'City2', N'3 ', N'2 ', N'1 ')
GO
INSERT [dbo].[_Details] ([Department], [Zone], [Place], [City], [L1], [L2], [L3]) VALUES (N'Department3', N'Zone3', N'Place3', N'City3', N'2 ', N'3 ', N'1 ')
GO
My Attempt
WITH _Details AS
(
SELECT L1 FROM _Details
UNION ALL
SELECT e.Name FROM _Employees e INNER JOIN _Details d ON e.Code = d.L1
)
SELECT * FROM _Details
Not sure what I am doing wrong?

Simply JOIN the tables:
SELECT
d.[Department], d.[Zone], d.[Place], d.[City],
e1.[Name] AS L1, e2.[Name] AS L2, e3.[Name] AS L3
FROM _Details d
LEFT JOIN _Employees e1 ON d.L1 = e1.Code
LEFT JOIN _Employees e2 ON d.L2 = e2.Code
LEFT JOIN _Employees e3 ON d.L3 = e3.Code

You only need joins. Join the employee table thrice, once per employee column. As L1, L2, and L3 are nullable, you need outer joins.
select
d.[Department], d.[Zone], d.[Place], d.[City],
e1.[Name] as name1,
e2.[Name] as name2,
e3.[Name] as name3
from [dbo].[_Details] d
left join [dbo].[_Employees] e1 on e1.[Code] = d.[L1]
left join [dbo].[_Employees] e2 on e2.[Code] = d.[L3]
left join [dbo].[_Employees] e3 on e3.[Code] = d.[L2];

Related

SQL tree data rebuild

Good morning,
I have an issue with a SQL query on hierarchic data.
I have to store the position of products on the shelfs in a supermarket.
Products can be moved but I have to maintain the history in order to produce sales statistics.
Records in the table are hierarchically linked and they can change some of their information and the position on the shelf.
Shelf_code: identify the shelf hierarchic position (i.e. aisle, shelf, level, sector…)
Shelf_position: details the location on shelf level.
parentId is set to null for the first insert occurrence of a record and is set to the ancestor record id for the further versions.
I’ve produced a tree structured set of records that can be shown like in the picture.
At the beginning of the year the products are positioned as follows
enter image description here
Then a new brand has been inserted between B and C and C has been moved in a different position (with his children C flavour x and C flavour y)
In the database new records are created for Brand C items with the new shelf code and position, parent id is now not null and corresponds to the id of the original record.
When I rebuild the supermarket shelfs tree, I want to show only the new positions
enter image description here
I tried to get data using partition over Shelf_position but I get twice the records named “Flowour x” and “Flowour y”: both in the correct position but also in the previous one (so they look like being Brand New sons that isn’t correct)
enter image description here
My query:
SELECT Shelfs.*
FROM Shelfs
WHERE Shelfs.ID IN(
SELECT id
FROM
(SELECT m.*, ROW_NUMBER() over
(partition by Shelf_Position order by m.time_stamp desc) as rn
FROM Shelfs m) m2
WHERE m2.rn = 1)
ORDER BY Shelf_Code, Shelf_Position
To get item genealogy of product named “Flavour x” I’ve used the query listed below.
Selecting the most recent item I can get the last one
WITH Anchestors AS (
SELECT Shelfs.*
,0 AS lv
FROM Shelfs
WHERE id = #productId
UNION ALL
SELECT parent.*
, lv+1 as lv
FROM Shelfs parent
INNER JOIN Anchestors a
ON parent.id = a.parentId
)
SELECT #rootId = ( SELECT top(1) id
FROM Anchestors
order by lv desc);
-- select root descendants
WITH generation AS (
SELECT Shelfs.*
,0 AS lv
FROM Shelfs
WHERE parentId IS NULL
and id = #rootId
UNION ALL
SELECT child.*
, lv+1 as lv
FROM Shelfs child
INNER JOIN generation g
ON g.id = child.parentId
)
SELECT *
FROM generation
order by lv
But this query is parametrized for a specific product and I wasn’t able to generalize it in order to get the last version of all the items.
Can anyone help me to find out the correct way to get the data?
Thanks in advance to everybody.
Database table script:
CREATE TABLE [dbo].[Shelfs](
[id] [uniqueidentifier] NOT NULL,
[Name] [nchar](10) NULL,
[Shelf_Code] [nvarchar](max) NULL,
[Shelf_Position] [nvarchar](max) NULL,
[parentId] [uniqueidentifier] NULL,
[time_stamp] [datetime] NULL,
CONSTRAINT [PK_Shelfs] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Shelfs] ADD CONSTRAINT [DF_Shelfs_id] DEFAULT (newid()) FOR [id]
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'043be568-8cc6-4624-9373-64d31a032745', N'Level 1 ', N'0101', N'010101', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'27ccf84c-5a08-425b-a355-6fb1f99eda3a', N'Flavour x ', N'0101010103', N'010101010301', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'9e841e78-571a-4009-8d40-81fc9045b99e', N'Brand C ', N'01010101', N'0101010104', N'37035b46-6a1a-47b6-8bdc-4a6ecfd68b9e', CAST(N'2022-02-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'da5119e1-c327-463a-b8e9-84453a1495cc', N'2nd Aisle ', N'00', N'02', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'b3e67cd1-c726-4bcf-a30c-9b7945a2ea9f', N'Left ', N'01', N'0101', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'08c2d2bb-0980-4d0d-899d-a4d23c0c7878', N'Flavour x ', N'0101010104', N'010101010401', N'27ccf84c-5a08-425b-a355-6fb1f99eda3a', CAST(N'2022-02-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'56825bd1-55ab-4c65-86c0-aff40550b785', N'Flavour y ', N'0101010103', N'010101010302', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'4a8e4ef7-926c-4eca-a520-b580f7035f44', N'Right ', N'01', N'0102', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'c53d35bc-f31b-4a67-a9e7-b82fbae5f7dc', N'Sector 1 ', N'010101', N'01010101', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'c70a6b81-8967-4ae8-a16c-bc6a925e1f61', N'Flavour y ', N'0101010104', N'010101010402', N'56825bd1-55ab-4c65-86c0-aff40550b785', CAST(N'2022-02-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'c46948f0-2d5e-48cf-a773-dcc44a434779', N'Brand B ', N'01010101', N'0101010102', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
INSERT [dbo].[Shelfs] ([id], [Name], [Shelf_Code], [Shelf_Position], [parentId], [time_stamp]) VALUES (N'63123c3e-36bf-477e-919b-f245f0ff80c2', N'Sector 2 ', N'010101', N'01010102', NULL, CAST(N'2022-01-01T08:00:00.000' AS DateTime))
I fancy I've found the solution for my issue.
For who has interest in it, here's the query:
WITH ShelfsTree([id]
,[Name]
,[Shelf_Code]
,[Shelf_Position]
,[parentId]
,[Time_stamp]
, lv)
AS (SELECT a.[id],
a.[Name],
a.[Shelf_Code],
a.[Shelf_Position],
a.[parentId] Parent,
a.[Time_stamp],
0 AS lv
FROM Shelfs a
WHERE a.[parentId] IS NULL
AND a.[parentId] IS NULL
UNION ALL
SELECT a2.[id],
a2.[Name],
a2.[Shelf_Code],
a2.[Shelf_Position],
a2.[parentId] Parent,
a2.[Time_stamp],
ShelfsTree.lv + 1 lv
FROM Shelfs a2
INNER JOIN ShelfsTree ON ShelfsTree.[id] = a2.[parentId]
WHERE a2.[parentId] IS NOT NULL
)
select *
from ShelfsTree
where id not in (select [parentId] from Shelfs where [parentId] is not null)
order by Shelf_Code, Shelf_Position, Time_stamp desc
Thanks.

Compare two tables and find differences in column values

I want to compare two tables (identical columns) and find out that what column value changed.
Here is an example with sample data.
employee_original table has 6 columns.
CREATE TABLE [dbo].[employee_original](
[emp_id] [int] IDENTITY(1,1) NOT NULL,
[first_name] [varchar](100) NOT NULL,
[last_name] [varchar](100) NOT NULL,
[salary] int NOT NULL,
[city] [varchar](20) NOT NULL,
[department] [varchar](20) NOT NULL,
PRIMARY KEY CLUSTERED
(
[emp_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO employee_original VALUES ( 'Julia', 'Schultz', 100, 'New York', 'Tech');
INSERT INTO employee_original VALUES ( 'Vincent', 'Trantow', 200, 'Moscow', 'HR');
INSERT INTO employee_original VALUES ( 'Whitney ', 'Pouros', 500, 'Miami', 'Accounting');
INSERT INTO employee_original VALUES ( 'Chandler', 'Osinski', 10, 'Singapore', 'Purchasing');
INSERT INTO employee_original VALUES ( 'Sydnie', 'Green', 700, 'Ireland', 'Operations');
INSERT INTO employee_original VALUES ( 'Josefa', 'Anderson', 800, 'Berlin', 'Purchase');
INSERT INTO employee_original VALUES ( 'Brayan', 'Bergstrom', 900, 'New York', 'Operations');
INSERT INTO employee_original VALUES ( 'Shyanne', 'Kris', 900, 'New York', 'Sales');
employee_modified has same employee but some of the attributes have changed for few employees.
CREATE TABLE [dbo].[employee_modified](
[emp_id] [int] IDENTITY(1,1) NOT NULL,
[first_name] [varchar](100) NOT NULL,
[last_name] [varchar](100) NOT NULL,
[salary] int NOT NULL,
[city] [varchar](20) NOT NULL,
[department] [varchar](20) NOT NULL,
PRIMARY KEY CLUSTERED
(
[emp_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO employee_modified VALUES ( 'Julia', 'Schultz', 100, 'New York', 'Tech');
INSERT INTO employee_modified VALUES ( 'Vincent', 'Wyman', 500, 'Moscow', 'HR');
INSERT INTO employee_modified VALUES ( 'Whitney ', 'Pouros', 500, 'Miami', 'Sales');
INSERT INTO employee_modified VALUES ( 'Chandler', 'Osinski', 10, 'Singapore', 'Purchasing');
INSERT INTO employee_modified VALUES ( 'Sydnie', ' Cartwright', 900, 'Ireland', 'Operations');
INSERT INTO employee_modified VALUES ( 'Joseph', 'Anderson', 800, 'Berlin', 'Purchase');
INSERT INTO employee_modified VALUES ( 'Bryan', 'Bergstrom', 900, 'Naples', 'Operations');
INSERT INTO employee_modified VALUES ( 'Shyanne', 'Jakubowski', 900, 'New York', 'Accounting');
I am looking for a result that can tell me what field changed for which employee.
e.g. emp_id =2 has last name and salary change. So output should look like:
emp_id attribute orignial_value new_value
2 last_name Trantow Wyman
2 salary 200 500
This is what I have tried so far:
(1) Join tables and find what changed :
DROP TABLE IF EXISTS #temp;
SELECT distinct
o.emp_id,
o.first_name [original_first_name], m.first_name [modified_first_name],
o.last_name [original_last_name], m.last_name [modified_last_name],
o.salary [original_salary], m.salary [modified_salary],
o.city [original_city], m.city [modified_city],
o.department [original_department], m.department [modified_department]
into #temp from
[dbo].[employee_original] o inner join [dbo].[employee_modified] m on o.emp_id = m.emp_id
select * from #temp
Gives me
(2) Self join with #temp and find out what attribute has changed.
-- All Last Name Changes.
select distinct t1.emp_id, t1.original_last_name, t2.modified_last_name
from #temp t1
inner join #temp t2 on t1.emp_id = t2.emp_id
where t1.original_last_name <> t2.modified_last_name
-- All Department changes
select distinct t1.emp_id, t1.original_department, t2.modified_department
from #temp t1
inner join #temp t2 on t1.emp_id = t2.emp_id
where t1.original_department <> t2.modified_department
Any pointers on how I can get to my desired result.
Here is an option that will dynamically unpivot your data without actually using dynamic SQL.
Example
Select emp_id
,[key]
,Org_Value = max( case when Src=1 then Value end)
,New_Value = max( case when Src=2 then Value end)
From (
Select Src=1
,emp_id
,B.*
From [employee_original] A
Cross Apply ( Select [Key]
,Value
From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES ) )
) B
Union All
Select Src=2
,emp_id
,B.*
From [employee_modified] A
Cross Apply ( Select [Key]
,Value
From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES ) )
) B
) A
Group By emp_id,[key]
Having max( case when Src=1 then Value end)
<> max( case when Src=2 then Value end)
Order By emp_id,[key]
Results
You can use the following code to unpivot all possible changes
SELECT
o.emp_id,
v.column_name,
v.old_value,
v.new_value
FROM employee_original o
JOIN employee_modified m ON o.emp_id = m.emp_id
CROSS APPLY (
SELECT 'first_name', CAST(o.first_name AS nvarchar(max)), CAST(m.first_name AS nvarchar(max))
WHERE o.first_name <> m.first_name
UNION ALL
SELECT 'last_name', o.last_name, m.last_name
WHERE o.last_name <> m.last_name
UNION ALL
SELECT 'salary', o.salary, m.salary
WHERE o.salary <> m.salary
UNION ALL
SELECT 'city', o.city, m.city
WHERE o.city <> m.city
UNION ALL
SELECT 'department', o.department, m.department
WHERE o.department <> m.department
) v(column_name, old_value, new_value);

MS SQL Server 2008 query - doesn't get proper send and received message count

SELECT DISTINCT
U.UserId as 'Id',
U.FullName as 'Name',
(SELECT COUNT(*) FROM [Conversation]
WHERE FromUserId = 'user1' AND ToUserId = U.UserId) 'SentCount',
(SELECT COUNT(*) FROM [Conversation]
WHERE ToUserId = 'user1' AND FromUserId = U.UserId) 'ReceivedCount'
FROM
[Conversation] C
INNER JOIN
[User] U ON U.UserId = C.FromUserId
WHERE
C.ToUserId = 'user1'
Query returns a result but it doesn't include some of the rows. Conversation table contains the same FromUserId (send message user) and ToUserId (receive message user).
Here are the tables :
Current result -
Expected result:
Table with dummy data -
CREATE TABLE [dbo].[User](
[Id] [int] NULL,
[UserId] [varchar](5) NULL,
[Name] [varchar](5) NULL,
[Email] [varchar](11) NULL
) ON [PRIMARY]
INSERT [dbo].[User] ([Id], [UserId], [Name], [Email]) VALUES (1, N'user1', N'user1', N'user1#a.com')
INSERT [dbo].[User] ([Id], [UserId], [Name], [Email]) VALUES (2, N'user2', N'user2', N'user2#a.com')
INSERT [dbo].[User] ([Id], [UserId], [Name], [Email]) VALUES (3, N'user3', N'user3', N'user3#a.com')
INSERT [dbo].[User] ([Id], [UserId], [Name], [Email]) VALUES (4, N'user4', N'user4', N'user4#a.com')
INSERT [dbo].[User] ([Id], [UserId], [Name], [Email]) VALUES (5, N'user5', N'user5', N'user5#a.com')
CREATE TABLE [dbo].[Conversation](
[Id] [int] NULL,
[conversationId] [varchar](14) NULL,
[messageId] [varchar](4) NULL,
[fromUserId] [varchar](5) NULL,
[toUserId] [varchar](5) NULL
) ON [PRIMARY]
INSERT [dbo].[Conversation] ([Id], [conversationId], [messageId], [fromUserId], [toUserId]) VALUES (1, N'con-user1user2', N'mes1', N'user1', N'user2')
INSERT [dbo].[Conversation] ([Id], [conversationId], [messageId], [fromUserId], [toUserId]) VALUES (2, N'con-user1user2', N'mes2', N'user1', N'user2')
INSERT [dbo].[Conversation] ([Id], [conversationId], [messageId], [fromUserId], [toUserId]) VALUES (3, N'con-user2user1', N'mes3', N'user2', N'user1')
INSERT [dbo].[Conversation] ([Id], [conversationId], [messageId], [fromUserId], [toUserId]) VALUES (4, N'con-user1user3', N'mes4', N'user1', N'user3')
INSERT [dbo].[Conversation] ([Id], [conversationId], [messageId], [fromUserId], [toUserId]) VALUES (5, N'con-user4user1', N'mes5', N'user4', N'user1')
Can someone help how to includes all the records?
Thanks!
You don't need a join in the outer query. This would be more simply written as:
SELECT U.UserId as Id, U.FullName as Name,
(SELECT COUNT(*)
FROM [Conversation] c
WHERE c.FromUserId = 'user1' AND c.ToUserId = U.UserId
) as SentCount,
(SELECT COUNT(*)
FROM [Conversation] c
WHERE c.ToUserId = 'user1' AND c.FromUserId = U.UserId
) as ReceivedCount
FROM [User] U ;
Notes:
Qualify all column references. This is particularly important for correlation clauses.
Give tables aliases that are abbreviations for the table names.
Only use single quotes for string and date constants. Do not use the for column aliases.
Here is a db<>fiddle.
You don't need the conversation table at your base select. Something like this would work, but can be optimised with subqueries:
Select U.UserId as 'Id',
U.name as 'Name',
isnull(fromSummed.sentCount, 0) 'SentCount',
isnull(ToSummed.ReceivedCount, 0) 'ReceivedCount'
FROM [User] U
outer apply (select count(*) as sentCount from [Conversation] cFrom where cFrom.FromUserId = 'user1' and ToUserId = U.UserId ) fromSummed
outer apply (select count(*) as ReceivedCount from [Conversation] cTo where cTo.ToUserId = 'user1' and cTo.FromUserId = U.UserId) ToSummed
where isnull(fromSummed.sentCount, 0)>0 or isnull(ToSummed.ReceivedCount, 0)>0

SQL left join for inactive records

I have 2 tables. One of them has actual names and the other one has nicknames used by those people.
CREATE TABLE [dbo].[Customer](
[id] [int] IDENTITY(1,1) NOT NULL,
[firstName] [varchar](50) NULL,
[lastName] [varchar](50) NULL,
[active] [bit] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[CustomerAKA](
[id] [int] NULL,
[akaFirstName] [varchar](50) NULL,
[akaLastName] [varchar](50) NULL
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Customer] ON
INSERT [dbo].[Customer] ([id], [firstName], [lastName], [active]) VALUES (1, N'Op', N'Test', 0)
INSERT [dbo].[Customer] ([id], [firstName], [lastName], [active]) VALUES (2, N'M', N'J', 1)
INSERT [dbo].[Customer] ([id], [firstName], [lastName], [active]) VALUES (3, N'John', N'Doe', 1)
SET IDENTITY_INSERT [dbo].[Customer] OFF
INSERT [dbo].[CustomerAKA] ([id], [akaFirstName], [akaLastName]) VALUES (1, N'Hello', N'Test')
INSERT [dbo].[CustomerAKA] ([id], [akaFirstName], [akaLastName]) VALUES (1, N'Mahalo', N'Test')
INSERT [dbo].[CustomerAKA] ([id], [akaFirstName], [akaLastName]) VALUES (3, N'Jonny', N'Doe')
My query is :
select *
from dbo.Customer c1
left join dbo.CustomerAKA c2 on c2.id = c1.id
where not exists ( select *
from dbo.Customer c
where c.id = c1.id
and c.active = 0 )
Even though Op Test is not active, I still want to get the nicknames for him:
1 Hello Test
1 Mahalo Test
So my output should be :
M J
John Doe
Jonny Doe
Hello Test
Mahalo Test
Any ideas?
I think you want union all:
select c.firstname, c.lastname
from customer c
union all
select ca.akafirstname, c.akalastname
from customeraka ca join
customer c
on ca.id = c.id
where c.active = 1;
Try this:
/*
WITH
Customer (id, firstName, lastName, active) AS
(
VALUES
(1, 'Op', 'Test', 0)
, (2, 'M', 'J', 1)
, (3, 'John', 'Doe', 1)
)
, CustomerAKA (id, akaFirstName, akaLastName) AS
(
VALUES
(1, 'Hello', 'Test')
, (1, 'Mahalo', 'Test')
, (3, 'Jonny', 'Doe')
)
*/
SELECT firstName, lastName
FROM Customer
WHERE active = 1
UNION ALL
SELECT c2.akaFirstName AS firstName, c2.akaLastName AS lastName
FROM CustomerAKA c2
JOIN Customer c1 ON c1.id=c2.id;
Not sure about what you want
But seems something like
select *
from dbo.Customer c1
left join dbo.CustomerAKA c2 on c2.id = c1.id
where c1.active = 1 or (c1.firstname = "Op" and c1.lastname = "Test")
Order by c1.active desc
Or like
select
coalesce(c2.firstname, c1.firstname) as firstname,
coalesce(c2.lastname, c1.lastname) as lastname
from dbo.Customer c1
Left outer join dbo.CustomerAKA c2 on c2.id = c1.id
Order by c1.active desc

how to get table from first table when data is not there in second table

i have requirement where i need to show data of both tables when both the ID's are same.when id is present in first table and not there in second table i need to show data from first table
CREATE TABLE [dbo].[TEST](
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Test_History](
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Test_History] Script Date: 06/19/2015 19:01:49 ******/
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'A', CAST(0x0000A4BC01347E88 AS DateTime))
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'I', CAST(0x0000A4BC0134A390 AS DateTime))
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (2, N'Rohan', N'A', CAST(0x0000A4BC01391FCC AS DateTime))
/****** Object: Table [dbo].[TEST] Script Date: 06/19/2015 19:01:49 ******/
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (2, N'Rohan', N'I', CAST(0x0000A4BC0138D584 AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'A', CAST(0x0000A4BC013072DC AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (3, N'Raj', N'A', CAST(0x0000A4BC0138DED7 AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (4, N'Krishna', N'A', CAST(0x0000A4BC0138EE31 AS DateTime))
so far i have tried my query to achieve the result
select T.ID,COALESCE(T.ID,TT.ID),T.Name,COALESCE(T.Name,TT.Name),T.status,COALESCE(T.status,TT.status)
from Test T LEFT JOIN (Select TOP 1 ID,MIN(Name)name,Status from Test_History
GROUP BY ID,status
)TT
ON T.ID = TT.ID
where T.ID = 3
Id = 1 and 2 present show i will get data from both tables
Id = 3 and 4 not present in the table
so using coalesce i will get the data
from first table and show in 2nd table column also
but is there any other way like both tables are same structure
i'm thinking of
Declare #tablename varchar(10)
IF EXISTS (SELECT 1 from TESt where id = #id)
IF COunt there in both tables
SET #tablename = Test
ELSE
SET #tablename = Test_history
select * from #tablename where id = #ID
can i get any solution like this
You can use EXCEPT.
Here is an example:
SELECT a,b
FROM (
VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10)
) AS MyTable(a, b)
EXCEPT
SELECT a,b
FROM (
VALUES (1, 2), (7, 8), (9, 10)
) AS MyTable(a, b);
This will return all rows of the upper statement, which are not in the second statement.
First: Thanks for the excellent setup for the data related to the question!
If your real question was if table variables can be used as described in your question, the answer is no; or more accurately that its not worth it.
Not recommended:
declare #TableName TABLE (
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL)
IF EXISTS (SELECT 1 from TESt where id = #id)
INSERT INTO #TableName SELECT * FROM dbo.TEST WHERE ID = #ID
ELSE INSERT INTO #TableName SELECT * FROM dbo.[Test_History] WHERE ID = #ID
select * from #tablename where id = #ID
Here's the solution I prefer:
DECLARE #ID INT = 3;
SELECT * FROM [dbo].[TEST] ss WHERE ss.id = #id
UNION ALL SELECT * FROM [dbo].[Test_History] th WHERE th.id = #id
and not exists ( SELECT * FROM [dbo].[TEST] ss WHERE ss.id = #id);
UNION ALL performs surprisingly well - don't forget the ALL keyword, and I am assuming that ID is a PK or AK.
If I'm understanding correctly and you want to display all records that match between the two tables and only records from first table when the id does not exist in the second in the same result set, then all you need is a simple left join:
SELECT *
FROM dbo.test t
LEFT OUTER JOIN Test_History th
ON t.id = th.id
WHERE t.id = #id