2009-04-20 38 views
5

Tôi đang tìm cách tạo chế độ xem lấy dữ liệu từ hai bảng "Lịch biểu" và "Tham chiếu".Tham gia nhiều cột trong một bảng vào một cột trong một bảng khác

Lịch biểu có hơn 50 cột (gần như hoàn toàn không chuẩn hóa - không phải thiết kế của tôi), hầu hết trong số đó chứa giá trị có thể được nối với một cột trong bảng Tham chiếu.

Làm cách nào để viết câu lệnh SQL để nối chính xác từng cột trong Lịch biểu với cột đơn trong Tham chiếu?

Bảng lịch được định nghĩa là:

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] 

Và bảng tham chiếu được định nghĩa là:

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] 

Tôi cố gắng để tham gia mỗi [TEXT1_ ]/[TEXT2_] cột trong Lên lịch cho cột [SCHAREACODE] để tham khảo. Tất cả các bảng tham chiếu chứa là một danh sách các khu vực mà nhân viên có thể làm việc.

+0

Vui lòng cập nhật câu hỏi của bạn với ví dụ về các bảng của bạn và RDBMS bạn đang sử dụng - ví dụ: MySQL, SQL Server, vv – Seb

+0

Mỗi cột trong Lịch biểu có tham gia vào một COLUMN trong tham chiếu hay bạn thực sự có ý nghĩa với ROW không? Vui lòng cung cấp ví dụ (ví dụ: 3 trong số 50 cột.) –

+0

TEXTn là một danh sách được phân tách bằng dấu phẩy hoặc chỉ một mã vùng duy nhất? –

Trả lời

0

Từ câu hỏi được cập nhật

Có lẽ một cái gì đó như thế này? Nó sẽ được lộn xộn không có vấn đề gì bạn làm.

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 
+0

Tôi nghi ngờ đây có thể là cách duy nhất. –

6

tôi nghĩ anh ấy có nghĩa là tham gia vào các bảng tham khảo nhiều lần:

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 
+0

Điều gì sẽ xảy ra nếu tôi muốn chọn vài cột từ Bảng tham chiếu? Nó sẽ giống như "Chọn R1.ID, R2.ID, R3.ID, R4.ID ......." – nakul

1

Mô tả của bạn là một chút thiếu, vì vậy tôi sẽ cho rằng

Schedule có Hơn 50 cột (nó gần như hoàn toàn không chuẩn hóa - không phải thiết kế của tôi), hầu hết trong số đó chứa một giá trị có thể được nối với một cột trong bảng Tham chiếu.

có nghĩa là 1 trong số 50 cột trong Lịch biểu là ReferenceId. Vì vậy, với một thiết kế bảng như:

Schedule (MaybeReferenceId1, MaybeReferenceId2, MaybeReferenceId3, ...) 
Reference (ReferenceId) 

Cái gì như:

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 
    ... 

sẽ làm việc. Bạn có thể đơn giản hóa nó bằng cách sử dụng IN nếu RDBMS của bạn hỗ trợ nó:

SELECT * 
FROM Schedule 
JOIN Reference ON 
    Reference.ReferenceId IN (
     Schedule.MaybeReferenceId1, 
     Schedule.MaybeReferenceId2, 
     Schedule.MaybeReferenceId3, 
     Schedule.MaybeReferenceId4, 
     ... 
    ) 
0

Đồng ý với TheSoftwareJedi, nhưng có thể tôi chỉ đề nghị sử dụng LEFT JOIN để thất bại đến trận đấu không gây Schedule hàng của bạn biến mất ?

Tất nhiên, thực hiện 28 THAM GIA sẽ hơi cồng kềnh bất kể chi tiết.

Tôi không chắc chắn tôi muốn gọi đây là "denormalized", nhiều "abnormalized" ... :-)

+0

Tôi cho rằng điều đó phụ thuộc: nếu db nhận ra rằng bạn đang tham gia vào cùng một bảng, sau đó nó có thể nhận ra rằng slurping bảng đó vào một băm trong bộ nhớ là một kế hoạch hợp lý. Giản đồ không đẹp, nhưng tôi đã thấy tồi tệ hơn. – araqnid

0

Hãy thử một truy vấn như thế này:

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 
.. 

Bạn nên thể nhận được kết quả tương tự với các kết nối truyền thống vì vậy tôi khuyên bạn nên thử nghiệm với điều đó.

Các vấn đề liên quan