Đăng ký học Excel - PivotTable 3 buổi tối (31/7, 2 và 4/8) - TPHCM

Hỏi về câu lệnh SQL trong Oracle tạo View điền khuyết thông tin

Thảo luận trong 'Cơ sở dữ liệu' bắt đầu bởi kyo, 13 Tháng bảy 2017.

  1. kyo

    kyo Nguyễn Khắc Duy Staff Member

    Gửi mọi người,

    kyo có một vấn đề muốn nhờ mọi người giúp đỡ. kyo có 2 bảng dữ liệu như sau:

    Bảng 1: bao gồm 3 cột LINE, STARTDATE và MOLD

    upload_2017-7-13_11-46-45.png

    Bảng 2: bao gồm rất nhiều cột thông tin khác, nhìn chung cũng có LINE và PRODDATE. Và bảng này là bảng có rất đầy đủ các thông tin các ngày (từ ngày 22/6 đến ngày 12/7)

    Bài toán kyo muốn giải quyết là các giá trị MOLD của bảng 1 sẽ điền khuyết vào bảng 2 sau khi kyo inner join (để tạo ra bảng 3) với LINE = LINE và STARTDATE < = PRODDATE. Cụ thể là ví dụ, trong phạm vi từ ngày 22 đến 26, thông tin của bảng 3 với giá trị MOLD là A, sau đó ngày 27 thì bảng 3 điền giá trị C và ngày 28 trở đi đến ngày 12/7 sẽ điền giá trị là JA.

    kyo làm câu lệnh như sau:
    Tuy nhiên kết quả sau cùng thì nó bị trùng lắp khi qua ngày 27, cụ thể nó sẽ xuất hiện cả MOLD A và C (mong muốn là ngày 27 chỉ có MOLD C mà thôi), rồi ngày 28 thì xuất hiện cả 3 MOLD luôn (mong muốn là ngày 28 chỉ có MOLD JA).

    upload_2017-7-13_12-5-32.png

    Mọi người giúp kyo chỉnh lại câu lệnh SQL với (kyo dùng SQL trong Oracle).

    Cảm ơn mọi người.
     
  2. Hai Lúa Miền Tây

    Hai Lúa Miền Tây Thành viên gạo cội Staff Member Super Moderator

    Kyo thêm 1 cái join nữa là mold của bảng 1 với mold bảng 2 thử nhé
     
    kyo thích bài này.
  3. kyo

    kyo Nguyễn Khắc Duy Staff Member

    Là sao anh? Bảng 2 không có mold anh, chỉ có bảng 1 thôi. Mà em cần thông tin của bảng 2 và điền thêm giá trị mold của bảng 1 nên mới tạo 1 cái view (bảng 3) để xem.
     
  4. eke_rula

    eke_rula Thành viên tích cực

    Em nghĩ do anh đặt điều kiện này (b.startdate<=proddate) nên nó lậy vậy là đúng rồi, anh sửa lại (b.startdate=proddate) thử xem!!!
     
  5. Hai Lúa Miền Tây

    Hai Lúa Miền Tây Thành viên gạo cội Staff Member Super Moderator

    Thường thì người ta hiết kế trong bảng 1 thêm 1 trường ID làm khóa chính, Bảng 2 cũng có thêm 1 trường ID, trường ID của bảng 1 có quan hệ 1 - nhiều với trường ID của bảng 2. Như vậy sẽ không gặp rắc rối như trường hợp trên. Còn trường hợp lấy ngày để join thì cũng chưa ổn lắm.
     
  6. AutoReply

    AutoReply Thành viên hoạt động

    theo tôi hiểu thì kyo muốn truy vấn kiểu này nè
    Mã:
    select * from yearly_ae_model_v_2years a OUTER APPLY
    (select top 1 * from mold_ij_used b where a.line = b.line and b.startdate <= a.proddate
    order by startdate desc) x
    nhưng mà orcacle không biết có hỗ trợ OUTER APPLY ko , hên xui.
     
    kyo thích bài này.
  7. VetMini

    VetMini Thành viên gạo cội

    Oracle 12c bắt đầu có Cross Appply, Outer Apply, và Lateral (Inline View). Chủ thớt muốn dùng cái nào thì cứ tự nhiên.
     
  8. kyo

    kyo Nguyễn Khắc Duy Staff Member

    Cảm ơn mọi người, sau khi áp dụng thì kyo đã làm được với câu lệnh như sau:

    Tuy nhiên 1 vấn đề khác phát sinh là khi kyo dùng create view testing as với câu lệnh trên thì Oracle báo lỗi không cho tạo view. Kyo có nghiên cứu qua một số hướng dẫn thì họ nói là chỉ có thể sử dụng join nếu muốn tạo view chứ không thể dùng apply. Không biết mọi người có hướng khắc phục nào giúp kyo với.

    Cảm ơn mọi người.
     
  9. eke_rula

    eke_rula Thành viên tích cực

    Nếu mà câu lệch SQL bình thường thì em sẽ viết như vầy, còn Oracel thì không biết sao!!
    PHP:
    SELECT *,f.mold from yearly_ae_model_v_2years e ;
    LEFT JOIN ;
    (
    SELECT c.startdate,d.line,d.MOLD FROM (SELECT a.startdateMIN(b.startdate) as startdate1 FROM yearly_ae_model_v_2years a ;
    LEFT JOIN ;
    mold_ij_used b ON a.startdate<=b.startdate GROUP BY  a.startdate;
    LEFT JOIN;
    mold_ij_used d ON c.startdate1=d.startdatef  ON e.line=f.line AND f.startdate=e.startdate
     
  10. VetMini

    VetMini Thành viên gạo cội

    Tôi trông sơ thì có vẻ bạn muốn lấy mọt cái ngày startdate gần ngày proddate nhất.
    Trường hợp này có thể thử cách tính min(proddate - startdate)
     
  11. AutoReply

    AutoReply Thành viên hoạt động

    ủa trước khi xuống dòng phải đặt dấu ";" hả bạn ? đây là hệ CSDL nào bá đạo vậy bạn ? Chứ trong hệ thống SQL Server tôi chưa nhìn thấy. Xin bạn minh thị cho tôi được mở rộng hiểu biết. +-+-+-++-+-+-+
     
    eke_rula thích bài này.
  12. eke_rula

    eke_rula Thành viên tích cực

    Trong visual foxpro đấy anh ạ, tài khoản sql server của em bi khóa rồi nên em dùng fox để test, sql server thì xuống dòng bình thường!!!
     
    AutoReply thích bài này.
  13. AutoReply

    AutoReply Thành viên hoạt động

    bạn nói bạn dùng chính câu lệnh trên để tạo View ? không biết là bạn muốn dùng select * để minh họa cho người khác hiểu hay thật sự đã đem chuỗi select * để tạo View ?
    Hi vọng các vị nick màu đỏ không làm tôi thất vọng chứ.
    Câu lệnh của bạn đương nhiên không thể dùng để tạo View nếu dùng trong môi trường SQL server . Đơn giản vì trong đó có 2 cột trùng tên (line) chứ không phải vì có OUTER APPLY.
    Nếu thật sự Oracle không cho tạo View vì có OUTER APPLY thì cũng không sao , có thể chuyển truy vấn trên thành INNER JOIN dễ dàng, nó phụ thuộc mức độ ngẫu hứng của bạn. Bạn nên tự luyện xem sao.
    Tôi không biết gì về dữ liệu của bạn, nhưng đoán 90 % khả năng cặp cột (line,StartDate) trong bảng mold_ij_used phải Unique, như thế là đủ để thực hiện INNER JOIN. Hoặc xui mà rớt vào 10 % khả năng còn lại cũng không sao, truy vấn có thêm chút hấp dẫn.
     
  14. VetMini

    VetMini Thành viên gạo cội

    Hình như đường chuyền sản xuất này thì ở một line, khi một Mold bắt đầu thì Mold kia chấm dứt? (cán thép hay đúc cái gì đó?)
    Muốn đi đường ngoại đạo hôn?
    Nếu C luôn luôn start sau A và trước JA thì loại cái Mold ra khỏi group và bên kết quả thay bằng Max(Mold)
    Nếu C không luôn đi sau A thì vẫn có cách: nối startdate vào trước Mold. Như vậy Max(startdateMold) sẽ đưa ra đúng cái đi sau. Bên kết quả thì tách ra trở lại.

    Select SubStr(Max(To_Char(startdate, "yyyymmdd") || mold),9) as Mold, max(startdate) as moldstart, focus_factory, proddate, a.line, bundle, week, month, EFRTMIN
    from yearly_ae_model_v_2years a inner join mold_ij_used b on a.line = b.line
    and (b.startdate<=proddate)
    group by focus_factory, proddate, a.line, bundle, week, month,EFRTMIN
    order by proddate

    (tuy ngoại đạo nhưng có thể dùng SQL tiêu chuẩn mà không phải dựa vào đặc tính của phiên bản nào)
     
    Lần chỉnh sửa cuối: 15 Tháng bảy 2017
  15. VetMini

    VetMini Thành viên gạo cội

    Hổng biết rồi cuối cùng chủ thớt giải quyết ra sao nhỉ?
    Bắt thường bạn Xe Hơi Làm Lại Lốp đấy. Bạn phán cái gì khiến chủ thớt bỏ chạy mất dép rồi.
     
    AutoReply thích bài này.

Chia sẻ trang này