2010-01-06 58 views
6

Tôi có truy vấn T-SQL sau (một trường hợp thử nghiệm đơn giản) chạy tốt trong MS SQL nhưng không thể nhận được truy vấn tương đương trong MS Access (JET-SQL). Vấn đề là các tiêu chí bổ sung trong LEFT JOIN. Làm cách nào để thực hiện điều này trong MS Access?LEFT JOINing trên tiêu chí bổ sung trong MS Access

T-SQL:

SELECT * FROM A 
LEFT OUTER JOIN B ON A.ID = B.A_ID 
       AND B.F_ID = 3 

JET-SQL (những gì tôi có cho đến nay nhưng treo truy cập!):

SELECT * FROM dbo_A 
LEFT JOIN dbo_B ON (dbo_A.ID = dbo_B.A_ID AND dbo_B.F_ID = 3) 
+0

Không cần các dấu ngoặc trên tiêu chí kết hợp –

+0

Có quan trọng là ví dụ T-SQL là tham gia ngoài không? Tất cả các hoạt động cơ bản của nó là trả về tất cả các hàng trong A. – Melvin

+0

@OMG Ponies - Không có dấu ngoặc đơn, tôi nhận được lỗi cú pháp, với chúng, Access crashes ... @Melvin - Không, từ OUTER là tùy chọn. – Supergibbs

Trả lời

10

Bạn cần phải sử dụng một subselect để áp dụng các điều kiện:

SELECT * 
    FROM dbo_A LEFT JOIN 
    [SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3]. AS dbo_B 
     ON dbo_A.ID = dbo_B.A_ID; 

Nếu bạn đang chạy truy cập với chế độ "SQL 92" tương thích bật, bạn có thể làm tiêu chuẩn hơn:

SELECT * 
    FROM dbo_A LEFT JOIN 
    (SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3) AS dbo_B 
     ON dbo_A.ID = dbo_B.A_ID; 

Bạn có cần điều này để có thể chỉnh sửa trong Access không? Nếu không, chỉ cần sử dụng truy vấn passthrough với T-SQL nguyên gốc. Nếu vậy, tôi có khả năng sẽ tạo ra một cái nhìn phía máy chủ cho điều này, và tôi đặc biệt muốn di chuyển nó phía máy chủ nếu giá trị bằng chữ là thứ bạn sẽ tham số hóa (ví dụ, F_ID = 3 thực sự là F_ID = N trong đó N là một giá trị được chọn khi chạy).

BTW, tôi viết các bảng câu lệnh SQL có nguồn gốc được chọn này mỗi ngày trong khi làm việc trong Access. Nó không phải là một thỏa thuận lớn.

+0

Có, tôi biết tôi có thể sử dụng một subselect, nhưng nó chậm hơn đáng kể vì vậy tôi muốn sử dụng một tham gia trái. Tôi không biết về các tùy chọn truy vấn passthrough mặc dù, mà làm việc hoàn hảo! (thông tin thêm cho những người khác tại đây: http://support.microsoft.com/kb/303968). Tôi đang đánh dấu câu trả lời của bạn là được chấp nhận vì nó đã hoạt động. Cảm ơn! – Supergibbs

+1

Cho dù subselect chậm hơn phụ thuộc vào hai điều: 1) làm thế nào cơ sở dữ liệu tham gia tối ưu hóa subselect so với thay thế, và một trong những rõ ràng trong trường hợp này, 2) có hay không các tùy chọn thậm chí có sẵn. Trong máy bay phản lực/ACE SQL nó không phải là vì bạn không thể có một đa lĩnh vực tham gia được xác định theo hướng ngược lại (tức là, một từ A => B và khác từ B => A). Nó có thể là SQL Server tối ưu hóa subelect suboptimally trong so sánh ngón chân thay thế, nhưng nếu bạn đang sử dụng Jet/ACE, bạn sẽ phải tuân theo quy tắc của Jet/ACE, do đó đề cập đến passthroughs. –

+1

Tôi khá chắc chắn một tham gia trái luôn luôn nhanh hơn một subselect. Chắc chắn, trong một tập dữ liệu nhỏ hoặc nếu công cụ DB của bạn có thể tối ưu hóa (AKA biến subelect của bạn thành một tham gia bên trái), bạn sẽ không thấy sự khác biệt, nhưng "một bên trái tham gia sau đó một lựa chọn n hàng" sẽ nhanh hơn " n + 1 chọn ". Chắc chắn trong trường hợp của tôi SQL Server chạy bên trái tham gia nhanh hơn. – Supergibbs

-4

Đó tình trạng cuối cùng về mặt kỹ thuật là không phải là một tham gia nhưng sự so sánh với giá trị bằng chữ. Đặt nó vào một mệnh đề WHERE:

SELECT * 
FROM a LEFT OUTER JOIN b ON a.ID = b.a_id 
WHERE b.f_id = 3; 
+5

Điều đó không đúng. Việc kiểm tra F_ID = 3 trong điều kiện kết nối bên trái sẽ cho bạn giá trị rỗng cho tất cả các giá trị từ B khi F_ID = 3. Đặt nó vào mệnh đề where sẽ không trả về giá trị nào cả. – lins314159

+0

Xin lỗi, ý tôi là bạn bị vô hiệu khi F_ID <> 3 tham gia trái. – lins314159

1

Bạn có nhận được thông báo lỗi khi nó bị treo hoặc không khóa máy? Đánh giá bởi tên dbo_B tôi sẽ đoán rằng đây là những bảng được liên kết trong Access. Tôi tin rằng khi bạn tham gia như vậy Access không nói với máy chủ SQL rằng nó cần kết quả của việc nối, nó nói, "Hãy cho tôi tất cả các hàng của cả hai bảng" sau đó nó cố gắng tham gia với chính nó. Nếu các bảng rất lớn, điều này có thể khiến ứng dụng bị khóa.

Có lẽ bạn nên tạo chế độ xem trên SQL Server cho những gì bạn cần.

+0

Chắc chắn là một ý tưởng tốt, điều đó có nghĩa là cú pháp của tôi là chính xác chỉ Access không thể xử lý nó? – Supergibbs

+0

Tôi không biết liệu bản thân Access có giới hạn kỹ thuật hay không, nhưng nếu các bảng là hàng triệu hàng thì PC mà Access đang hoạt động cũng như mạng mà dữ liệu phải truyền tải có thể bị choáng ngợp. –

+0

Hoàn toàn không đúng khi Jet/ACE yêu cầu toàn bộ bảng và tự tham gia, trừ khi có điều gì đó ngăn cản Jet/ACE lấy siêu dữ liệu cần thiết để xác định xem nó có thể truyền toàn bộ điều đó cho máy chủ hay không. là trường hợp 99% thời gian). Hoặc, nó có thể là có một cái gì đó về các bảng được liên kết (có thể là quan điểm, ví dụ) ngăn cản Jet/ACE thực hiện công việc. Đó là hai trường hợp duy nhất tôi có thể nghĩ rằng điều đó có thể khiến Jet/ACE yêu cầu các bảng đầy đủ với SQL được cung cấp.Tóm lại, nó rất, rất khó xảy ra. –