2012-09-17 41 views
21

Tôi có một truy vấn lấy dữ liệu từ ba bảng bằng cách sử dụng LEFT OUTER JOIN cho cả hai phép nối. Tôi cần truy vấn để trả lại thông tin bên trái nhất (bảng Salesrep) ngay cả khi không có dữ liệu tương ứng trong hai bảng bên phải (người kê đơn và đơn thuốc tương ứng). Khi tôi chạy truy vấn này mà không có các tham số ngày trong mệnh đề WHERE, tôi nhận được lợi tức mong đợi, nhưng ngay sau khi tôi bao gồm các tham số ngày, tôi không nhận được gì khi không có dữ liệu phù hợp cho một salesrep. Tôi cần ít nhất xem các cột bảng salesrep được yêu cầu trong truy vấn.Bên ngoài tham gia không hoạt động?

Đây là truy vấn ... bất kỳ trợ giúp nào đều được đánh giá cao.

SELECT salesrep.salesrepid as SalesRepID, 
     salesrep.fname as SalesrepFName, 
     salesrep.lname as SalesRepLName, 
     salesrep.fname+' '+salesrep.lname as SalesRepFullName, 
     prescriber.dea_no as PDeaNo, 
     prescriber.lname+', '+prescriber.fname as DocName, 
     CONVERT(VARCHAR(8), prescriptions.filldate, 1) as FillDate, 
     prescriptions.drugname as DrugName, 
     prescriptions.daysupply as Supply, 
     prescriptions.qtydisp as QtyDisp, 
     prescriptions.rx_no as Refill, 
     prescriptions.copay as Sample, 
     ROUND(prescriptions.AgreedToPay-(prescriptions.AgreedToPay*.07),2) as AgreedToPay, 
     prescriptions.carrierid as CarrierID 
FROM salesrep 
    LEFT OUTER JOIN prescriber on salesrep.salesrepid = prescriber.salesrepid 
    LEFT OUTER JOIN prescriptions on prescriber.dea_no = prescriptions.dea_no 
    WHERE salesrep.salesrepid = 143 AND 
     prescriptions.filldate >= '09-01-12' AND 
     prescriptions.filldate <= '09-17-12' 
ORDER BY prescriptions.filldate 
+1

DBMS nào? (Tắt chủ đề, nhưng tôi ghét đại diện ma túy và ngành công nghiệp dược phẩm) – Kermit

+3

@njk (Tắt chủ đề) điều này không đáng ngạc nhiên chút nào, xem xét một xu hướng truyền thông mạnh mẽ chống lại ngành công nghiệp :) – dasblinkenlight

Trả lời

53

Bạn nên di chuyển khó khăn về prescriptions.filldate vào tình trạng ON của kết nối, và loại bỏ nó từ where khoản:

LEFT OUTER JOIN prescriptions ON prescriber.dea_no = prescriptions.dea_no 
          AND prescriptions.filldate >= '09-01-12' 
          AND prescriptions.filldate <= '09-17-12' 

Nếu không, các mục mà không có cuối prescriptions với null s trong số prescriptions.filldate và mệnh đề WHERE ném chúng đi.

+0

Cảm ơn dasblinkenlight! – jgiven

0

Điều này là do sự bất bình đẳng prescriptions.filldate của bạn đang lọc ra các hàng salesrep không có giá trị trong cột prescriptions.filldate. Vì vậy, nếu có giá trị null (không có dữ liệu phù hợp từ bảng bên phải), thì toàn bộ hàng, bao gồm dữ liệu bán hàng được lọc bởi bộ lọc ngày - vì null không rơi vào giữa hai ngày.

11

Here bạn có thể tìm mô tả ngắn gọn về các giai đoạn xử lý truy vấn (điều này phổ biến đối với hầu hết các DBMS). Bạn sẽ tìm thấy trên mạng, mà cho OUTER JOIN:

  1. Descartes đầu tiên THAM GIA được sản xuất,
  2. so với điều kiện ON được thực hiện trên kết quả bộ sản xuất tập hợp con của các hàng,
  3. sau hơn hàng bên ngoài được nối với NULL trên các cột được nối trong bảng bên trong,
  4. trên kết quả đó, mệnh đề WHERE được áp dụng thực hiện lọc.

Khi bạn đặt điều kiện trong mệnh đề WHERE chạm vào các hàng của bảng bên ngoài, tất cả đều bị loại bỏ. Bạn chỉ cần đặt điều kiện đó trong mệnh đề ON, vì điều đó được đánh giá trước khi các hàng bên ngoài được nối thêm.

Vì vậy, những điều kiện:

prescriptions.filldate >= '09-01-12' AND 
prescriptions.filldate <= '09-17-12' 

nên được chuyển thành khoản ON.

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