Stored procedure throws an error while getting data from two table using UNION - sql

I have two tables which are shown in this screenshot:
I am writing a stored procedure which will return data from both tables:
ALTER PROCEDURE [dbo].[GetInventoryDetails]
#MaterialId INT
AS
BEGIN
SELECT
tms.Material_ID AS MaterialId,
tmm.Name As MaterialName,
CONVERT(varchar,Quantity) AS AddedQuantity,
UtilizedQuantity ='-',
tcl.LedgerName AS SupplierName,
UsedFor = '-',
tmm.CurrentStock,
tmm.OpeningStock,
CONVERT(DATETIME,CONVERT(VARCHAR(100), tms.Material_Date, 112)) AS MaterialDate,
tms.Narration AS Narration
FROM
tblMaterialSheet tms
JOIN
tblMaterialMaster tmm ON tmm.Material_ID = tms.Material_ID
JOIN
tblCompanyLedger tcl ON tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND tms.isActive = 1
UNION
SELECT
tmu.Material_ID AS MaterialId,
tmm.Name As MaterialName,
AddedQuantity = '-',
CONVERT(varchar,Utilized_Quantity) AS UtilizedQuantity,
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112)) AS MaterialDate,
SupplierName = '-',
tbst.Name AS UsedFor,
tmm.CurrentStock,
tmm.OpeningStock,
tmu.Narration As Narration
FROM
tblMaterialUtilization tmu
JOIN
tblMaterialMaster tmm ON tmm.Material_ID = tmu.Material_ID
JOIN
tblBuildingSubTask tbst ON tbst.BuildingSubTask_ID = tmu.BuildingSubTask_ID
WHERE
tmu.Material_ID = #MaterialId
AND tmu.isActive = 1
END
When I call the stored procedure, it throws an error:
Conversion failed when converting date and/or time from character string.
Table structure: tblmaterialsheet
CREATE TABLE [dbo].[tblMaterialSheet]
(
[MaterialSheet_ID] [int] IDENTITY(1,1) NOT NULL,
[Company_ID] [int] NOT NULL,
[User_ID] [int] NOT NULL,
[BuildingSubTask_ID] [int] NOT NULL,
[Material_Date] [datetime] NOT NULL,
[Material_ID] [int] NOT NULL,
[Unit_ID] [int] NOT NULL,
[Quantity] [decimal](10, 2) NOT NULL,
[Size_ID] [int] NULL,
[Height] [decimal](6, 2) NULL,
[Width] [decimal](6, 2) NULL,
[Rate_Per_Unit] [money] NULL,
[Paid_Amount] [money] NULL,
[Total_Amount] [money] NULL,
[Vehical_No] [varchar](50) NULL,
[Ledger_ID] [int] NULL,
[Narration] [varchar](max) NULL,
[Challan_No] [int] NULL,
[Bill_ID] [int] NULL,
[isBilled] [bit] NOT NULL,
[Approval] [varchar](50) NULL,
[Approval_ModifiedDate] [datetime] NULL,
[UploadImage] [image] NULL,
[isActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
Table structure : tblMaterialUtilization
CREATE TABLE [dbo].[tblMaterialUtilization]
(
[MaterialUtilization_ID] [int] IDENTITY(1,1) NOT NULL,
[Company_ID] [int] NOT NULL,
[User_ID] [int] NOT NULL,
[BuildingSubTask_ID] [int] NOT NULL,
[Material_ID] [int] NOT NULL,
[Utilization_Date] [datetime] NOT NULL,
[Utilized_Quantity] [decimal](10, 2) NOT NULL,
[Narration] [varchar](max) NOT NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
Table structure : tblMaterialMaster
CREATE TABLE [dbo].[tblMaterialMaster]
(
[Material_ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](100) NOT NULL,
[Unit_ID] [int] NOT NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
[OpeningStock] [numeric](18, 0) NULL,
[PurchaseLedger] [numeric](18, 0) NULL,
[CurrentStock] [numeric](18, 0) NULL
)
Table structure : tblBuildingSubTask
CREATE TABLE [dbo].[tblBuildingSubTask]
(
[BuildingSubTask_ID] [int] IDENTITY(1,1) NOT NULL,
[BuildingTask_ID] [int] NOT NULL,
[Name] [varchar](200) NOT NULL,
[Narration] [varchar](max) NULL,
[StartDate] [datetime] NULL,
[TargetCompletionDate] [datetime] NULL,
[ActualCompletionDate] [datetime] NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
How to solve this error?

TRY THIS NOW: The order of the column were not in the same order so it was getting the different datatype values for the same column. Datatype and Order is most important in the UNION
ALTER PROCEDURE [dbo].[GetInventoryDetails]
#MaterialId int
AS
BEGIN
SELECT
tms.Material_ID AS MaterialId,
tmm.Name As MaterialName,
CONVERT(varchar,Quantity) AS AddedQuantity,
UtilizedQuantity ='-',
tcl.LedgerName AS SupplierName,
UsedFor='-',
tmm.CurrentStock,
tmm.OpeningStock,
CONVERT(DATETIME,CONVERT(VARCHAR(100), tms.Material_Date, 112)) AS MaterialDate,
tms.Narration As Narration
FROM
tblMaterialSheet tms
JOIN tblMaterialMaster tmm on tmm.Material_ID = tms.Material_ID
JOIN tblCompanyLedger tcl on tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND
tms.isActive = 1
UNION
SELECT
tmu.Material_ID AS MaterialId,
tmm.Name As MaterialName,
AddedQuantity = '-',
CONVERT(varchar,Utilized_Quantity) AS UtilizedQuantity,
SupplierName = '-', --Moved up
tbst.Name AS UsedFor, --Moved up
tmm.CurrentStock, --Moved up
tmm.OpeningStock, --Moved up
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112)) AS MaterialDate,
tmu.Narration As Narration
FROM
tblMaterialUtilization tmu
JOIN tblMaterialMaster tmm on tmm.Material_ID = tmu.Material_ID
JOIN tblBuildingSubTask tbst on tbst.BuildingSubTask_ID = tmu.BuildingSubTask_ID
WHERE
tmu.Material_ID = #MaterialId
AND
tmu.isActive = 1
END

The troubleshooting direction I'd take:
Look at your SQL. You're looking for anything that might be converting something of non-date type to date type. Your error probably means there's data somewhere you're converting to date that can't be converted. Be aware that this can include comparisons or functions that output a date.
Looking at your example, without knowing that actual data types, the only place I can see this happening is the explicit CONVERT functions on tms.Material_Date and Utilization_Date. I'd quickly comment these out and run each of the halves of the UNION separately. If they work, I could uncomment one or other until I figure out which field is causing the error. If they work independently but not unioned, I know that it's the after-union fields getting converted to date because the pre-union field is date.
Say it's the first half, before the union. I'd run:
SELECT * As Narration
FROM
tblMaterialSheet tms
JOIN tblMaterialMaster tmm on tmm.Material_ID = tms.Material_ID
JOIN tblCompanyLedger tcl on tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND
tms.isActive = 1
AND
ISDATE(tms.Material_Date) = 0
You might need to work outwards in your converting to see where it falls over, e.g.,
AND
ISDATE(CONVERT(VARCHAR(100), tms.Material_Date, 112))
Then you should have a good idea about the problem.
Incidentally,
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112))
looks very odd - what are you trying to achieve here by converting a date to varchar and back?

When you write a UNION or UNION ALL, You should make sure the following
No of Columns should be Same for Each Select Should Be same
Data Type of Column coming on the same position of each select Should be same
Suppose I have a column with character datatype for the first select and I'm trying to union it with a DateTime datatype, then I will get the error
SELECT 'ABCD'
UNION ALL
SELECT GETDATE()
This will throw the error
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
because the datatypes do not match.
And this will cause another error:
SELECT 'ABCD',GETDATE()
UNION ALL
SELECT GETDATE()
Like this:
Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
because the number of columns does not match.
So make sure that the datatypes match for each column in your UNION and if they does not match, try Cast or Convert

Related

SQL Query to update a colums from a table base on a datetime field

I have 2 table called tblSetting and tblPaquets.
I need to update 3 fields of tblPaquets from tblSetting base on a where clause that use a datetime field of tblPaquest and tblSetting.
The sql below is to represent what I am trying to do and I know it make no sense right now.
My Goal is to have One query to achieve this goal.
I need to extract the data from tblSettings like this
SELECT TOP(1) [SupplierID],[MillID],[GradeFamilyID] FROM [tblSettings]
WHERE [DateHeure] <= [tblPaquets].[DateHeure]
ORDER BY [DateHeure] DESC
And Update tblPaquets with this data
UPDATE [tblPaquets]
SET( [SupplierID] = PREVIOUS_SELECT.[SupplierID]
[MillID] = PREVIOUS_SELECT.[MillID]
[GradeFamilly] = PREVIOUS_SELECT.[GradeFamilyID] )
Here the table design
CREATE TABLE [tblSettings](
[ID] [int] NOT NULL,
[SupplierID] [int] NOT NULL,
[MillID] [int] NOT NULL,
[GradeID] [int] NOT NULL,
[TypeID] [int] NOT NULL,
[GradeFamilyID] [int] NOT NULL,
[DateHeure] [datetime] NOT NULL,
[PeakWetEnable] [tinyint] NULL)
CREATE TABLE [tblPaquets](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PaquetID] [int] NOT NULL,
[DateHeure] [datetime] NULL,
[BarreCode] [int] NULL,
[Grade] [tinyint] NULL,
[SupplierID] [int] NULL,
[MillID] [int] NULL,
[AutologSort] [tinyint] NULL,
[GradeFamilly] [int] NULL)
You can do this using CROSS APPLY:
UPDATE p
SET SupplierID = s.SupplierID,
MillID = s.MillID
GradeFamilly = s.GradeFamilyID
FROM tblPaquets p CROSS APPLY
(SELECT TOP (1) s.*
FROM tblSettings s
WHERE s.DateHeure <= p.DateHeure
ORDER BY p.DateHeure DESC
) s;
Notes:
There are no parentheses before SET.
I don't recommend using [ and ] to escape identifiers, unless they need to be escaped.
I presume the query on tblSettings should have an ORDER BY to get the most recent rows.

t-sql end of month insert

I have created two database tables named TSALESFACT and DimDate. TSALESFACT table contains the monthly sales target values. And DimTime contains the date values which begins from 01/01/2005.
CREATE TABLE [dbo].[TSalesFact](
[DateID] [smalldatetime] NULL,
[YearID] [int] NOT NULL,
[MonthID] [int] NOT NULL,
[SeasonID] [char](10) NOT NULL,
[DepartmentID] [char](10) NOT NULL,
[SalesAmount] [int] NOT NULL
)
CREATE TABLE [dbo].[dim_Date](
[ID] [int] NOT NULL,
[Date] [datetime] NOT NULL,
[Day] [char](2) NOT NULL,
[DaySuffix] [varchar](4) NOT NULL,
[DayOfWeek] [varchar](9) NOT NULL,
[DOWInMonth] [tinyint] NOT NULL,
[DayOfYear] [int] NOT NULL,
[WeekOfYear] [tinyint] NOT NULL,
[WeekOfMonth] [tinyint] NOT NULL,
[Month] [char](2) NOT NULL,
[MonthName] [varchar](9) NOT NULL,
[Quarter] [tinyint] NOT NULL,
[QuarterName] [varchar](6) NOT NULL,
[Year] [char](4) NOT NULL,
[StandardDate] [varchar](10) NULL,
[HolidayText] [varchar](50) NULL)
I would like to INSERT these sales target values into a new table named DailySalesTargets. But, the main purpose of this operation is writing the target sales to the each of end of month date. All of the date values for the relevant month will be zero. My desired resultset for this operation is like below:
How can I achieve this? Any idea?
I think this is what you are trying to do.
insert into [DailySalesTargets]([DateID],[YearID],[MonthID],
[SeasonID],[DepartmentID],[SalesAmount])
select d.[Date],d.[Year],d.[Month]
,dptSeason.[SeasonID],dptSeason.[DepartmentID]
,case when EOMONTH(d.[Date])=s.[DateID] then s.[SalesAmount] else 0 end as [SalesAmount]
from [dbo].[dim_Date] d
cross join (select distinct [DepartmentID],[SeasonID] from [dbo].[TSalesFact]) dptSeason
left join [dbo].[TSalesFact] s on d.[Date] = s.[DateID]
and s.[DepartmentID]=dptSeason.[DepartmentID]
and s.[SeasonID]=dptSeason.[SeasonID]

cannot convert varchar to float in sql

These are my 2 tables
CREATE TABLE [dbo].[dailyRate](
[SYMBOL] [varchar](50) NULL,
[SERIES] [varchar](50) NULL,
[OPENPRICE] [varchar](50) NULL,
[HIGHPRICE] [varchar](50) NULL,
[LOWPRICE] [varchar](50) NULL,
[CLOSEPRICE] [varchar](50) NULL,
[LASTPRICE] [varchar](50) NULL,
[PREVCLOSE] [varchar](50) NULL,
[TOTTRDQTY] [varchar](50) NULL,
[TOTTRDVAL] [varchar](50) NULL,
[TIMESTAMPDAY] [varchar](50) NULL,
[TOTALTRADES] [varchar](50) NULL,
[ISIN] [varchar](50) NULL
)
CREATE TABLE [dbo].[cmpDailyRate](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[SYMBOL] [varchar](50) NULL,
[SERIES] [varchar](50) NULL,
[OPENPRICE] [decimal](18, 4) NULL,
[HIGHPRICE] [decimal](18, 4) NULL,
[LOWPRICE] [decimal](18, 4) NULL,
[CLOSEPRICE] [decimal](18, 4) NULL,
[LASTPRICE] [decimal](18, 4) NULL,
[PREVCLOSE] [decimal](18, 4) NULL,
[TOTTRDQTY] [bigint] NULL,
[TOTTRDVAL] [decimal](18, 4) NULL,
[TIMESTAMPDAY] [smalldatetime] NULL,
[TOTALTRADES] [bigint] NULL,
[ISIN] [varchar](50) NULL,
[M_Avg] [decimal](18, 4) NULL
)
this is my insert query to fetch data from table to another with casting
Collapse | Copy Code
INSERT into [Stock].[dbo].[cmpDailyRate]
SELECT [SYMBOL],[SERIES],Str([OPENPRICE], 18,4),Str([HIGHPRICE],18,4),
Str([LOWPRICE],18,4),Str([CLOSEPRICE],18,4),Str([LASTPRICE],18,4),Str([PREVCLOSE],18,4),convert(bigint,[TOTTRDQTY]),Str([TOTTRDVAL],18,4),
convert(date, [TIMESTAMPDAY], 105),convert(bigint,[TOTALTRADES]),[ISIN],null
FROM [Stock].[dbo].[DailyRate]
This query runs perfectly in SQL Server 2005, but it's causing errors in SQL Server 2008 (above query run also in SQL Server 2008 when installed; error arise in last few days)
Error :
Error cannot convert varchar to float
What to do?
One of your rows contains invalid data in the columns you are doing the float conversion (Str) on. Use the following strategy to work out which:
SELECT *
FROM [dailyRate]
WHERE IsNumeric([OPENPRICE]) = 0
OR IsNumeric([HIGHPRICE]) = 0
etc etc.
If you do not want to filter out data, a CASE statement might work better for you.
SELECT CASE
WHEN IsNumeric([OPENPRICE]) = 1 THEN [OPENPRICE]
ELSE NULL -- or 0 or whatever
END AS OPENPRICE,
CASE
WHEN IsNumeric([HIGHPRICE]) = 1 THEN [HIGHPRICE]
ELSE NULL -- or 0 or whatever
END AS [HIGHPRICE]
FROM [dailyRate]

Auditing trigger - Column name or number of supplied values does not match table definition

I am attempting to create a database trigger capable of creating a snapshot of a 'Transactions' table and storing it in an 'Audit' table along with information pertaining to the date of the inserting, updating or deleting of any rows of data.
Apologies in advance, but I'm very much a novice at this kinda stuff!
As it stands, my trigger is as follows:
create trigger AuditTransactions
on dbo.Transactions
after insert, update, delete
as
if exists(select * from inserted)
begin
if exists(select * from deleted)
begin
-- this is for an update
update Audit
set DeleteDate = getdate()
where TransactionId in (select TransactionId from deleted)
end
-- this is just for an insert
insert into Audit
select *, getdate() as CreateDate
from inserted
end
else
begin
-- this is just for a delete
update Audit
set DeleteDate = getdate()
where TransactionId in (select TransactionId from deleted)
end
go
And my audit table appears as follows:
CREATE TABLE [dbo].[Audit](
[TransactionId] [int] NOT NULL,
[InvoiceNumber] [nvarchar](1) NULL,
[InvoiceType] [nvarchar](1) NULL,
[InvoiceIssueDate] [datetime] NULL,
[InvoiceTotalexclVat] [nvarchar](1) NULL,
[InvoiceTotalVat] [numeric](18, 0) NULL,
[InvoiceDiscount] [numeric](18, 0) NULL,
[InvoiceTotalPayable] [numeric](18, 0) NULL,
[AccountCode] [nvarchar](1) NULL,
[Reference1] [nvarchar](1) NULL,
[Reference2] [nvarchar](1) NULL,
[Reference3] [nvarchar](1) NULL,
[Level1CustomOrg] [nvarchar](1) NULL,
[Level2CustomOrg] [nvarchar](1) NULL,
[Level3CustomOrg] [nvarchar](1) NULL,
[Level4CustomOrg] [nvarchar](1) NULL,
[ScanLocation] [nvarchar](1) NULL,
[ScanDateTime] [datetime] NULL,
[CaptureInkjetId] [nvarchar](1) NULL,
[CaptureBatchId] [nvarchar](1) NULL,
[CaptureDateTime] [datetime] NULL,
[InputSource] [nvarchar](1) NULL,
[CurrencyCode] [nvarchar](1) NULL,
[DebitCredit] [nvarchar](1) NULL,
[OrderNumberHeader] [nvarchar](1) NULL,
[SupplierName] [nvarchar](1) NULL,
[BancPaySupplierId] [nvarchar](1) NULL,
[SupplierIDERP] [nvarchar](1) NULL,
[PaymentDate] [datetime] NULL,
[DeliveryDate] [datetime] NULL,
[CustomRef1] [nvarchar](1) NULL,
[CustomRef2] [nvarchar](1) NULL,
[CustomRef3] [nvarchar](1) NULL,
[CustomRef4] [nvarchar](1) NULL,
[CustomRef5] [nvarchar](1) NULL,
[CustomRef6] [nvarchar](1) NULL,
[CustomRef7] [nvarchar](1) NULL,
[CustomRef8] [nvarchar](1) NULL,
[CustomRef9] [nvarchar](1) NULL,
[CustomRef10] [nvarchar](1) NULL,
[CustomRef11] [nvarchar](1) NULL,
[CustomRef12] [nvarchar](1) NULL,
[CustomRef13] [nvarchar](1) NULL,
[CustomRef14] [nvarchar](1) NULL,
[CustomRef15] [nvarchar](1) NULL,
[CustomAmount1] [numeric](18, 0) NULL,
[CustomAmount2] [numeric](18, 0) NULL,
[CustomAmount3] [numeric](18, 0) NULL,
[CustomAmount4] [numeric](18, 0) NULL,
[CustomAmount5] [numeric](18, 0) NULL,
[CustomDate1] [datetime] NULL,
[CustomDate2] [datetime] NULL,
[Country1] [nvarchar](1) NULL,
[Country2] [nvarchar](1) NULL,
[Country3] [nvarchar](1) NULL,
[Country4] [nvarchar](1) NULL,
[Country5] [nvarchar](1) NULL,
[Country6] [nvarchar](1) NULL,
[Country7] [nvarchar](1) NULL,
[Country8] [nvarchar](1) NULL,
[Country9] [nvarchar](1) NULL,
[Country10] [nvarchar](1) NULL,
[CheckedOut] [bit] NULL,
[CheckedOutDate] [datetime] NULL,
[BlobUrl] [nvarchar](1) NULL,
[GLCode] [nvarchar](1) NULL,
[RejectReason] [nvarchar](1) NULL,
[RejectComment] [nvarchar](1) NULL,
[ReferMessage] [nvarchar](1) NULL,
[PaymentTerms] [nvarchar](1) NULL,
[CheckedOutByUserId] [int] NULL,
[LastUpdatedByUserId] [int] NULL,
[TransactionFormatTypeId] [int] NULL,
[RequestOriginalStatusTypeId] [int] NULL,
[GLCodeComment] [nvarchar](1) NULL,
[SenderOrganizationId] [int] NULL,
[ReceiverOrganizationId] [int] NULL,
[TransactionStatusTypeId] [int] NULL,
[TransactionTypeId] [int] NULL,
[OrganizationId] [int] NULL,
[OrganizationId1] [int] NULL,
[CreateDate] [datetime] NOT NULL,
[DeleteDate] [datetime] NULL
) ON [PRIMARY]
GO
When attempting to execute the query for the trigger I am getting the following error message:
Msg 213, Level 16, State 1, Procedure AuditTransactions, Line 17
Column name or number of supplied values does not match table definition.
This appears to be the 'insert into Audit' command, but I have no idea what to do from here!
Any help will be hugely appreciated, thanks in advance!
INSERT seems to be rather poorly documented. For the VALUES() element, it states the following:
If the values in the Value list are not in the same order as the columns in the table or do not have a value for each column in the table, column_list must be used to explicitly specify the column that stores each incoming value.
(Emphasis added)
However, it is my understanding and belief that the same constraint applies, no matter what the source of values/rows are - that unless you exactly match all columns in the table, you need to provide the column_list.
Now, for your instance, it may be easier if you just provide a value for every column in the table:
insert into Audit
select *, getdate() as CreateDate,null as DeleteDate
from inserted
Now, my other observation is that all this mucking about with conditional control flow is rather pointless - an insert of 0 rows will have no effect, and an update using in against an empty table will similarly have no effect. So I'd just have:
create trigger AuditTransactions
on dbo.Transactions
after insert, update, delete
as
update Audit
set DeleteDate = getdate()
where TransactionId in (select TransactionId from deleted)
insert into Audit
select *, getdate() as CreateDate,null as DeleteDate
from inserted
insert into Audit
select *, getdate() as CreateDate, null
from inserted
Your "audit" table has more columns than you're inserting (the deleted date); you need to either name all the columns, or insert a null.
Stylistically, naming the columns is better - it makes it clear what goes where, and avoid bugs when you add new columns.

Joining multiple columns in one table to a single column in another table

I am looking to create a view that pulls data from two tables "Schedule" and "Reference".
Schedule has 50+ columns (it's almost completely denormalized -- not my design), most of which contain a value that could be joined to a column in the Reference table.
How do I write the SQL statement to correctly join each column in Schedules to the single column in Reference?
The Schedule table is defined as:
CREATE TABLE [dbo].[Schedule](
[ID] [int] NOT NULL,
[SCHEDULEWEEK] [datetime] NOT NULL,
[EMPNO] [numeric](10, 0) NOT NULL,
[EMPLNAME] [varchar](32) NULL,
[EMPFNAME] [varchar](32) NULL,
[EMPSENDATE] [datetime] NULL,
[EMPHIREDATE] [datetime] NULL,
[EMPTYPE] [char](1) NULL,
[EMPSTATUS] [char](1) NULL,
[SNREFUSALS] [tinyint] NULL,
[QUALSTRING] [varchar](128) NULL,
[JOBOVERSHIFTTYPE] [bit] NULL,
[SHORTNOTICE] [bit] NULL,
[SHORTNOTICEWAP] [bit] NULL,
[SHORTNOTICEPHONE] [varchar](32) NULL,
[LEADHAND] [bit] NULL,
[DUALCURRENCY] [bit] NULL,
[MIN100WINDOW] [bit] NULL,
[STATHOLIDAY] [bit] NULL,
[AREAOVERHOURS] [bit] NULL,
[DOUBLEINTERZONES] [bit] NULL,
[MAXDAYSPERWEEK] [tinyint] NULL,
[MAXHOURSPERWEEK] [numeric](10, 2) NULL,
[MAXHOURSPERSHIFT] [numeric](10, 2) NULL,
[MAXDOUBLESPERWEEK] [tinyint] NULL,
[ASSIGNEDDAYS] [tinyint] NULL,
[ASSIGNEDHOURS] [numeric](10, 2) NULL,
[ASSIGNEDDOUBLES] [tinyint] NULL,
[ASSIGNEDLOAHOURS] [numeric](10, 2) NULL,
[SHIFTNO1] [int] NULL,
[TEXT1_1] [varchar](64) NULL,
[TEXT2_1] [varchar](64) NULL,
[DAYFLAG1] [bit] NULL,
[COMMENT1] [text] NULL,
[SHIFTNO2] [int] NULL,
[TEXT1_2] [varchar](64) NULL,
[TEXT2_2] [varchar](64) NULL,
[DAYFLAG2] [bit] NULL,
[COMMENT2] [text] NULL,
[SHIFTNO3] [int] NULL,
[TEXT1_3] [varchar](64) NULL,
[TEXT2_3] [varchar](64) NULL,
[DAYFLAG3] [bit] NULL,
[COMMENT3] [text] NULL,
[SHIFTNO4] [int] NULL,
[TEXT1_4] [varchar](64) NULL,
[TEXT2_4] [varchar](64) NULL,
[DAYFLAG4] [bit] NULL,
[COMMENT4] [text] NULL,
[SHIFTNO5] [int] NULL,
[TEXT1_5] [varchar](64) NULL,
[TEXT2_5] [varchar](64) NULL,
[DAYFLAG5] [bit] NULL,
[COMMENT5] [text] NULL,
[SHIFTNO6] [int] NULL,
[TEXT1_6] [varchar](64) NULL,
[TEXT2_6] [varchar](64) NULL,
[DAYFLAG6] [bit] NULL,
[COMMENT6] [text] NULL
-- Snip
) ON [PRIMARY]
And the Reference table is defined as:
CREATE TABLE [dbo].[Reference](
[ID] [int] NOT NULL,
[CODE] [varchar](21) NOT NULL,
[LOCATIONCODE] [varchar](4) NOT NULL,
[SCHAREACODE] [varchar](16) NOT NULL,
[LOCATIONNAME] [varchar](32) NOT NULL,
[FLTAREACODE] [varchar](16) NOT NULL
) ON [PRIMARY]
I am trying to join each [TEXT1_]/[TEXT2_] column in Schedule to the [SCHAREACODE] column in reference. All the reference table contains is a list of areas where the employee could work.
I think he means to join on the Reference table multiple times:
SELECT *
FROM Schedule AS S
INNER JOIN Reference AS R1
ON R1.ID = S.FirstID
INNER JOIN Reference AS R2
ON R2.ID = S.SecondID
INNER JOIN Reference AS R3
ON R3.ID = S.ThirdID
INNER JOIN Reference AS R4
ON R4.ID = S.ForthID
Your description is a bit lacking, so I'm going to assume that
Schedule has 50+ columns (it's almost completely denormalized -- not my design), most of which contain a value that could be joined to a column in the Reference table.
means that 1 of the 50+ columns in Schedule is a ReferenceId. So, given a table design like:
Schedule ( MaybeReferenceId1, MaybeReferenceId2, MaybeReferenceId3, ... )
Reference ( ReferenceId )
Something like:
SELECT *
FROM Schedule
JOIN Reference ON
Schedule.MaybeReferenceId1 = Reference.ReferenceId
OR Schedule.MaybeReferenceId2 = Reference.ReferenceId
OR Schedule.MaybeReferenceId3 = Reference.ReferenceId
OR Schedule.MaybeReferenceId4 = Reference.ReferenceId
...
would work. You could simplify it by using IN if your RDBMS supports it:
SELECT *
FROM Schedule
JOIN Reference ON
Reference.ReferenceId IN (
Schedule.MaybeReferenceId1,
Schedule.MaybeReferenceId2,
Schedule.MaybeReferenceId3,
Schedule.MaybeReferenceId4,
...
)
From updated question
Perhaps something like this? It will be messy no matter what you do.
SELECT S.ID
S.TEXT1_1,
TEXT1_1_RID = COALESCE((SELECT MAX(R.ID) FROM Reference R WHERE R.SCHAREACODE = S.TEXT1_1), 0),
S.TEXT1_2,
TEXT1_2_RID = COALESCE((SELECT MAX(R.ID) FROM Reference R WHERE R.SCHAREACODE = S.TEXT1_2), 0),
...
FROM Schedule S
Agree with TheSoftwareJedi, but can I just suggest using LEFT JOINs so that failures-to-match don't cause your Schedule row to disappear?
Of course, doing 28 JOINs is going to be a bit cumbersome whatever the details.
I'm not sure I'd call this "denormalized", more "abnormalized" ... :-)
Try a query like this:
select s.*, r.schareacode from schedule s,
where
s.text1_1 = s.schareacode
or s.text2_1 = s.schareacode
or s.textx_x = s.schareacode
..
You should be able to get the same results with traditional joins so I recommend you experiment with that as well.