How to SELECT DISTINCT records with INNER JOIN? - sql

I have two tables Finance Commissions May2021 (FMAY) and Consolidated Client Codes (CCC).
Here is the code for Insert Into: For table FMAY
USE [FinanceCommissions26May2021]
GO
/****** Object: Table [dbo].[Finance_Commissions_May26_2021$] Script Date: 22/06/2021 11:06:26 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Finance_Commissions_May26_2021$](
[Lender Reference] [nvarchar](255) NULL,
[F2] [nvarchar](255) NULL,
[F3] [nvarchar](255) NULL,
[Client] [nvarchar](255) NULL,
[F5] [nvarchar](255) NULL,
[Supplier] [nvarchar](255) NULL,
[Product] [nvarchar](255) NULL,
[Settlement / Inception Date] [nvarchar](255) NULL,
[Base Value] [nvarchar](255) NULL,
[Original Loan Amount] [money] NULL,
[Adviser Split (%)*] [money] NULL,
[F12] [nvarchar](255) NULL,
[Supplier_Amount_(incl GST)] [money] NULL,
[Supplier_Amount_(GST)] [money] NULL,
[Adviser Share (ex GST)] [money] NULL,
[F16] [nvarchar](255) NULL,
[F17] [nvarchar](255) NULL,
[Adviser Share (GST)] [money] NULL,
[Adviser Share (incl GST)] [money] NULL,
[LastNameOnly] [nvarchar](255) NULL,
[FirstNameOnly] [nvarchar](255) NULL,
[FirstFourLastName] [nvarchar](255) NULL,
[ClientCode] [nvarchar](255) NULL,
[IndexMatch] [nvarchar](255) NULL,
[F25] [nvarchar](255) NULL,
[F26] [float] NULL
) ON [PRIMARY]
GO
FMAY
Table FMAY contains the following columns:
commission amounts
a Lender Reference Number
client names (LastName, FirstName).
This report comes in monthly and contains monthly commissions for some of the clients (usually contains 350-400 records).
CREATE TABLE [Finance_Commissions_May26_2021$] (
CommissionAmount,
LenderReferenceNumber,
ClientLastName,
ClientFirstName
)
& here is the code for table CCC:
USE [FinanceCommissions26May2021]
GO
/****** Object: Table [dbo].[Consolidated_ClientCodes$] Script Date: 22/06/2021 11:07:27 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Consolidated_ClientCodes$](
[FirstFourLastName] [nvarchar](255) NULL,
[ClientCode] [nvarchar](255) NULL,
[Client] [nvarchar](255) NULL
) ON [PRIMARY]
GO
CCC
Table CCC contains the following columns:
client names
(different format though - i.e. FirstName,LastName)
a client code (which is a unique identifier (Primary key) assigned to each client.
Client code takes the form of SMIT123.
e.g. for "John, Smith" it's SMIT123
for "Mark, Smith" it's SMIT345, and so on.
i.e. First Four letters of last name followed by a unique 3 digit code.
This table contains Client names and unique Client codes for ALL clients (more than 7000 records)
CREATE TABLE ['20210617145928-Exception - No C$'] (
ClientCode PRIMARY KEY, -- '\w\w\w\w\d\d\d'
FirstName,
LastName
)
The problem
My aim is : To assign this unique Client code to each client within the FMAY table.
Since there was NO common column between tables FMAY and CCC, I created a new column (FirstFourLastName) which parses out FirstFour letters of Last Name (like "SMIT") from both Tables.
Then using this new column (FirstFourLastName), I wrote code for Inner Join in SQL with an aim to assign the Unique "Client Code" to each record in table FMAY.
I am able to get the correct client code assigned but not able to ONLY select distinct records.
My code is:
select
FMAY.[Lender Reference],
CCC.Client,
CCC.ClientCode,
FMAY.FirstFourLastName,
FMAY.[Adviser Share (ex GST)],
FMAY.[Adviser Share (GST)],
FMAY.[Adviser Share (incl GST)],
FMAY.Product
from
[FinanceCommissions26May2021].[dbo].[Finance_Commissions_May26_2021$] FMAY
inner join [FinanceCommissions26May2021].[dbo].['20210617145928-Exception - No C$'] CCC on
FMAY.FirstFourLastName = CCC.FirstFourLastName
The above code is giving me 6300 records, with the correct client code attached to each record though! However, I only need to assign Client Code to the 350-400 records in the FMAY table.
How can I select distinct records for my problem please?

It looks like there might be multiple similar values for FirstFourLastName and with join on FirstFourLastName you're getting every combination possible. For example:
FMAY table
LenderReference
FirstFourLastName
123
smit
456
smit
CCC Table
clientcode
FirstFourLastName
smit123
smit
smit456
smit
Omitting all other columns, the inner join on FirstFourLastName would produce:
LenderReference
clientcode
FirstFourLastName
123
smit123
smit
123
smit456
smit
456
smit123
smit
456
smit456
smit
I would double check that the clientcode is definitely attaching correctly. If LenderReference is unique, you could run distinct count of clientcodes against it.

Related

Foreign key shows nulls (ssms)

I am trying to do a very simple task - to connect two tables with a foreign key. However, after successful creating of the key, the column in the main table is full of NULL values.
I tried to create the relationship both with a script and using 'Design table' option.
So, I have two tables - Swimmer (Has 100000 rows)
CREATE TABLE [dbo].[Swimmer](
[SwimmerID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[PassportNumber] [nvarchar](20) ,
[BirthDate] [date] NOT NULL,
[Gender] [nvarchar](5) ,
[Rank] [nvarchar](10) ,
[CoachID] [int] )
And Coach (has 10000 rows):
[CoachID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[PassportNumber] [nvarchar](20) )
I want to connect them by CoachID, so the column CoachID in Swimmer becomes a foreign key that references the column CoachID in Coach, however when I do, the column CoachID in Swimmer just shows NULL in every row.
My next task will be to create a one-to-many relationship (since one coach can instruct multiple swimmers), but for now I just want to figure out why the connection is not working

How to Insert duplicate rows in SQL Server table from excel?

I have an Excel sheet with the following columns:
[API], [BasePrice], [CREATIONDATE], [CREATIONDATETIME],
[DealerCode], [DealerName], [InvoiceNor], [MRP], [MaterialNumber]
I have to insert the data from these columns into a SQL Server table with the same column structure.
The challenge is: [InvoiceNor] and [MaterialNumber] are the columns that should be unique key in the table (order), but the data in Excel in these columns has duplicate rows and the columns [BasePrice], [MRP] in the same rows contain unique values.
How can I insert the data from Excel into a SQL Server table or suggest me the structure of the table?
Current Table structure is:
CREATE TABLE [dbo].[Order]
(
[API] [nvarchar](255) NULL,
[BasePrice] [float] NULL,
[CREATIONDATE] [datetime] NULL,
[CREATIONDATETIME] [datetime] NULL,
[DealerCode] [float] NULL,
[DealerName] [nvarchar](255) NULL,
[InvoiceNor] [float] NOT NULL,
[MRP] [float] NULL,
[MaterialNumber] [float] NOT NULL,
constraint uk_InvoiceNor_MaterialNumber UNIQUE (InvoiceNor
asc,MaterialNumber asc)
)
You cannot insert those unless
you remove the unique keys constraint, or
create a new table (ID Pk, InvoiceNor, MaterialNumber). Remove
InvoiceNor, MaterialNumber from your table and add ID Pk as a foreign
key

Nested SQL Queries 3 levels

I am using MS Access and having troubles writing a query(s) to get my end result. Maybe someone can lend a hand.
I have Projects, Tasks and SubTasks tables. Each table has a related table for "Assignees". meaning a project could be assigned to an employee but the child tasks could be assigned to a different employee and still further the subtasks could then be assigned to other employees.
Now, when displaying this on screen, and I query for an employee that has been assigned to any project/Task/Subtask. I need that data to display but not other data. So for instance if the employee I query for only has been assigned to a task, then that project and task should display, but no additional projects/tasks/ and no subtasks. Likewise, if I query for an employee that only has been assigned to a subtask, then I only want to see the associated project and task. I think I can complete this with a series of queries...i think... but is there a slick method I can use to create this data.
Simply a select query with a series of joins could possibly work, but it doesnt because when an employee has been assigned to a subtask only and not to a project or task.
Thanks for any assistance!
Updated with additional information:
Table Structures:
CREATE TABLE [dbo].[Projects](
[ProjectID] [int] IDENTITY(1,1) NOT NULL,
[ProjectName] [varchar](100) NULL,
[ClientID] [int] NULL,
CREATE TABLE [dbo].[PM_ProjectAssignee](
[AssigneeID] [int] IDENTITY(1,1) NOT NULL,
[ProjectID] [int] NULL,
[EmployeeID] [int] NULL,
CREATE TABLE [dbo].[PM_ProjectTasks](
[ProjectTaskID] [int] IDENTITY(1,1) NOT NULL,
[ProjectID] [int] NULL,
[TaskID] [smallint] NULL,
CREATE TABLE [dbo].[PM_TaskAssignee](
[AssigneeID] [int] IDENTITY(1,1) NOT NULL,
[ProjectTaskID] [int] NULL,
[EmployeeID] [int] NULL,
CREATE TABLE [dbo].[PM_ProjectSubTasks](
[ProjectSubTaskID] [int] IDENTITY(1,1) NOT NULL,
[ProjectTaskID] [int] NULL,
[SubTaskDesc] [varchar](255) NULL,
CREATE TABLE [dbo].[PM_SubTaskAssignee](
[AssigneeID] [int] IDENTITY(1,1) NOT NULL,
[ProjectSubTaskID] [int] NULL,
[EmployeeID] [int] NULL,
With regards to queries I have tried...alot. I was implementing a scenario where I ended up with about a half dozen different queries all culminating into one (some of the queries where built with code to allow filtering) However the last one tried was:
SELECT ProjectID, ProjectName, EmployeeID, ProjectTaskID, EmployeeID, Association, ProjectSubTaskID, EmployeeID
FROM (qrTest3_Project LEFT JOIN qrTest2_Task ON qrTest3_Project.ProjectID = qrTest2_Task.ProjectID) LEFT JOIN qrtest1_SubTask ON qrTest2_Task.ProjectTaskID = qrtest1_SubTask.Association
WHERE (((qrTest3_Project.EmployeeID)=8)) OR (((qrTest2_Task.EmployeeID)=8)) OR (((qrtest1_SubTask.EmployeeID)=8));
the above query included other queries that simply joined each project/task/subtask to their respective assignee table. I can post those as well if needed.
I hope that provides the additional information you need? If not, happy to provide more.
Thanks!
I think I may have figured it out..as I sort of suspected, I was making it a bit more difficult then it needed to be. Simply joins really with criteria gives me the data I need and can work with.
SELECT PM_ProjectAssignee.ProjectID, PM_ProjectTasks.ProjectTaskID, PM_ProjectSubTasks.ProjectSubTaskID
FROM (((PM_ProjectAssignee
LEFT JOIN PM_ProjectTasks
ON PM_ProjectAssignee.ProjectID = PM_ProjectTasks.ProjectID)
LEFT JOIN PM_ProjectSubTasks
ON PM_ProjectTasks.ProjectTaskID = PM_ProjectSubTasks.ProjectTaskID)
LEFT JOIN PM_TaskAssignee
ON PM_ProjectTasks.ProjectTaskID = PM_TaskAssignee.ProjectTaskID)
LEFT JOIN PM_SubTaskAssignee
ON PM_ProjectSubTasks.ProjectSubTaskID = PM_SubTaskAssignee.ProjectSubTaskID
WHERE (((PM_ProjectAssignee.EmployeeID)=14))
OR (((PM_TaskAssignee.EmployeeID)=14))
OR (((PM_SubTaskAssignee.EmployeeID)=14))
GROUP BY PM_ProjectAssignee.ProjectID, PM_ProjectTasks.ProjectTaskID, PM_ProjectSubTasks.ProjectSubTaskID;

Get value from other foreign key table based on current table value

I am working on a project where I need to extract the data from excel sheet to SQL Server
, well that bit have done successfully. Now my problem is that for a particular column
called product size, I want to update current table based on product size in other table, I am really very confused , please help me out
Please find the table structure
CREATE TABLE [dbo].[T_Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[PartNo] [nvarchar](255) NULL,
[CategoryID] [int] NULL,
[MaterialID] [float] NULL,
[WireformID] [float] NULL,
[ProductName] [nvarchar](50) NULL,
[ProductSize] [nvarchar](50) NULL,
[ProductLength] [varchar](20) NULL,
[ProductActive] [bit] NULL,
[ProductImage] [varchar](60) NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[T_ProductSize](
[Code] [int] IDENTITY(1,1) NOT NULL,
[ProductSize] [nvarchar](50) NULL,
[Length] [nchar](20) NULL
) ON [PRIMARY]
GO
OK, so ignore the previous answer, I got the wrong end of the stick!!
You want something like this I think:
UPDATE T_Product
SET [ProductLength] = ps.[Length]
FROM T_Product p
INNER JOIN T_ProductSize ps
ON p.[ProductSize] = ps.[ProductSize]
That will take the Length value from T_ProductSize and place it in T_Product.ProductLength based on the value of T_Product.ProductSize
You mention a foreign key but you haven't included a definition for it. Is it between the two tables in your example? If so, which columns make the key? Is product size the key? If so, then your question doesn't make a lot of sense as the value will be the same in both tables.
Is it possible that you mean the product size is to be stored in a separate table and not in the T_Product table? In that case then instead of ProductSize in T_Product you will want the code from the T_ProductSize table (can I also suggest that instead of 'code' you call it 'ProductSizeCode' or better yet 'ProductSizeId' or similar? having columns simply called code can be very confusing as you have no simple way of know what table that value is in). Also, you should always create a primary key on each table: You cannot have a foreign key without one. They don't have to be clustered, that will depend upon hwo your search the table, but I am using a clustered PK for this example. That would give you something like this:
CREATE TABLE [dbo].[T_Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[PartNo] [nvarchar](255) NULL,
[CategoryID] [int] NULL,
[MaterialID] [float] NULL,
[WireformID] [float] NULL,
[ProductName] [nvarchar](50) NULL,
[ProductSizeId] [int] NOT NULL,
[ProductLength] [varchar](20) NULL,
[ProductActive] [bit] NULL,
[ProductImage] [varchar](60) NULL
CONSTRAINT [PK_T_Product] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[T_ProductSize](
[ProductSizeId] [int] IDENTITY(1,1) NOT NULL,
[ProductSize] [nvarchar](50) NULL,
[Length] [nchar](20) NULL
CONSTRAINT [PK_T_ProductSize] PRIMARY KEY CLUSTERED
(
[ProductSizeId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
--Now add your foreign key to T_Product.
ALTER TABLE [T_Product] WITH NOCHECK ADD CONSTRAINT [FK_Product_ProductSize] FOREIGN KEY([ProductSizeId])
REFERENCES [T_ProductSize] ([ProductSizeId])
GO
ALTER TABLE [T_Product] CHECK CONSTRAINT [FK_Product_ProductSize]
GO
Now, to retrieve your product along with the product size use something like this:
SELECT p.[ProductID], p.[PartNo], p.[CategoryID], p.[MaterialID], p.[WireformID], p.[ProductName],
ps.[ProductSize], ps.[Length], p.[ProductLength], p.[ProductActive], p.[ProductImage]
FROM [T_Product] p
INNER JOIN [T_ProductSize] ps
ON ps.[ProductSizeId] = p.[ProductSizeId]
If I have understood you correctly, then this is what I think you're after. If not, then have another go at explaining what it is you need and I'll try again.
Try this...
UPDATE t2
SET t2.ProductLength = t1.Length
FROM dbo.T_ProductSize t1
INNER JOIN dbo.T_Product t2 ON t1.ProductSize = t2.ProductSize

SQL Server 2008 find and replace elements in XML column

In the following table:
CREATE TABLE [dbo].[GDB_ITEMS](
[ObjectID] [int] NOT NULL,
[UUID] [uniqueidentifier] NOT NULL,
[Type] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](226) NULL,
[PhysicalName] [nvarchar](226) NULL,
[Path] [nvarchar](512) NULL,
[Url] [nvarchar](255) NULL,
[Properties] [int] NULL,
[Defaults] [varbinary](max) NULL,
[DatasetSubtype1] [int] NULL,
[DatasetSubtype2] [int] NULL,
[DatasetInfo1] [nvarchar](255) NULL,
[DatasetInfo2] [nvarchar](255) NULL,
[Definition] [xml] NULL,
[Documentation] [xml] NULL,
[ItemInfo] [xml] NULL,
[Shape] [geometry] NULL,
CONSTRAINT [R2_pk] PRIMARY KEY CLUSTERED
(
[ObjectID] ASC
)
ALTER TABLE [dbo].[GDB_ITEMS] WITH CHECK ADD CONSTRAINT [g1_ck] CHECK (([Shape].[STSrid]=(4326)))
GO
The [Documentation] column contains several hundred xml items and elements. I am trying to figure out to, with T-SQL, replace one series of elements:
<NPS_Info>
<MetaPurp>NPS</MetaPurp>
<NPS_Unit>
<UnitCode>MANDATORY for Data Store: NPS Alpha Unit Code (ACAD)</UnitCode>
<UnitType>MANDATORY for Data Store: NPS Unit Type (National Park, National Monument, etc)</UnitType>
</NPS_Unit>
</NPS_Info>
With this:
<NPS_Info>
<MetaPurp>NPS</MetaPurp>
<MetaPurp>CSDGM</MetaPurp>
<MetaPurp>OnlineData</MetaPurp>
<NPS_Unit>
<UnitCode>ABCD</UnitCode>
<UnitType>Park</UnitType>
</NPS_Unit>
<DatStore>
<Category>Landscape</Category>
<Category>Monitoring</Category>
<Category>Resource Management</Category>
<DSteward>
<cntinfo>
<cntperp>
<cntper>Something</cntper>
</cntperp>
<cntaddr>
<addrtype>mailing and physical</addrtype>
<address>1 Smith Lane</address>
<address></address>
<city>Anywhere</city>
<state>ST</state>
<postal>12345</postal>
</cntaddr>
<cntemail>email#email.com</cntemail>
</cntinfo>
</DSteward>
</DatStore>
</NPS_Info>
Please forgive my clumsy cut n' paste. There are several thousand rows in this table, however, not all of them have the xml element described in the first code block (this is a global table that holds descriptions of ALL tables in the DB, some [Documentation] records will contain non-pertinent xml not of interest to this operation).
You can use XML Data Modification Language (XML DML)
This code will change the content of the first node named NPS_Info with the content in variable #XML.
-- Delete everything in node NPS_Info
update YourTable
set XMLCol.modify('delete //NPS_Info[1]/*')
-- Insert #XML to node NPS_Info
update YourTable
set XMLCol.modify('insert sql:variable("#XML") into (//NPS_Info)[1]')
Working sample on SE Data