2014-11-26 15 views
12

Tôi có một truy vấn mà trông giống như:Có thể thực hiện truy vấn phụ với Sequelize.js không?

select es.EssayId, (esmax.WordCount - esmin.WordCount) 
from (select es.EssayId, min(es.EssayDate) as mined, max(es.EssayDate) as maxed 
     from EssayStats es 
     group by es.EssayId 
    ) es join 
    EssayStats esmin 
    on es.EssayId = esmin.EssayId and es.mined = esmin.EssayDate join 
    EssayStats esmax 
    on es.EssayId = esmax.EssayId and es.maxed = esmax.EssayDate; 

Có thể viết những dòng này với Sequelize.js ORM? Tôi biết tôi chỉ có thể sử dụng một trực tiếp query, nhưng tôi tự hỏi nếu nó có thể xây dựng.

+1

Tôi không nghĩ như vậy. Việc tải xuống có thể là điều gần nhất. [Đây là một ví dụ trong đó phần tiếp theo tạo ra một truy vấn con thông qua tải háo hức, vì một 'giới hạn' nhân tạo] (https://github.com/sequelize/sequelize/issues/1719). – bishop

+1

Tôi không biết gì về 'Sequelize.js'. Có thể soạn một cái gì đó như 'EssayStats t1 LEFT JOIN EssayStats t2 ON t1.EssayId = t2.EssayId AND t1.EssayDate axiac

Trả lời

3

Tôi không nghĩ câu trả lời rõ ràng cho câu hỏi của bạn là có thể. Xem #1869:

Truy vấn trên mô hình/bảng tham gia thông qua hiện không khả thi.

Để trả lời câu hỏi tiêu đề, Phần tiếp theo sẽ tự động tạo truy vấn con (ví dụ: #1719), nhưng bạn không thể thực hiện truy vấn con tùy chỉnh. Tôi không có một tài liệu tham khảo có thẩm quyền cho một tiêu cực.


Dường như bảng của bạn là một cái gì đó như thế này:

EssayStats 
    EssayId 
    EssayDate 
    WordCount 

Sau đó, bạn có thể làm một cái gì đó như thế này:

return EssayStat.findAll({ 
    attributes: [ 
     [sequelize.literal('((SELECT wordCount FROM "EssayStats" WHERE "EssayId" = "EssayStat"."EssayId" EssayStat BY "createdAt" DESC LIMIT 1) - (SELECT wordCount FROM "EssayStats" WHERE "EssayId" = "EssayStat"."EssayId" EssayStat BY "createdAt" ASC LIMIT 1))'), 'difference'], 
     'EssayId' 
    ], 
    group: ['EssayId'] 
}); 

Tất cả những gì nó đang làm đang chạy hai truy vấn SELECT, lấy MAX và MIN từ các truy vấn đó sau khi đặt hàng theo biến quan tâm của bạn và sau đó lấy sự khác biệt của bạn. Điều đó sẽ cung cấp cho bạn những gì bạn quan tâm: sự khác biệt về số lượng từ giữa phiên bản mới nhất và phiên bản đầu tiên.

Bí quyết ở đây là đóng gói câu lệnh SELECT trong trường thuộc tính.

Tất nhiên, nó lộn xộn như heck và có lẽ không phải tất cả tốt hơn nhiều so với đóng hộp sequelize.query. Nhưng nó trả lời ý chính của câu hỏi của bạn.

Một giải pháp tốt hơn có thể là không chuẩn hóa dữ liệu của bạn một số và lưu trữ "wordCountDelta" trực tiếp trong mô hình Tiểu luận của bạn. Sau đó, bạn có thể có một số afterCreatehook để tự động cập nhật trường. Điều đó rất có thể sẽ là giải pháp nhanh nhất.

Tôi đã trả lời điều gì đó tương tự here.

1

một ví dụ cho subquery

ModelA.findAll({ 
    where: { 
     $or: [ 
      {'$B.someColumn$' : someCondition}, 
      {'$C.someOtherColumn$' : someOtherCondition} 
     ] 
    }, 
    include: [{ 
     model: ModelB, 
     required: false, //true or false for required 
     where:{id:$id} 

    }, { 
     model: ModelC, 
     required: false, //true or false for required 
     where:{id:$id} 
    }] 
}); 

tôi hy vọng hữu ích: D

+0

Hi @Derit, ở đây tôi muốn một số bí danh tên cho Model A, Model B tham gia đầu ra và một lần nữa tham gia đầu ra đó với mô hình C. Có cách nào để làm điều đó. Ví dụ: chọn uid, col1, col2, col3 từ (chọn A.id là uid, col1, col2, col3 từ A tham gia bên trong B trong A.id = B.mid trong đó somecondition) là 't' inner join user as u on t.uid = u.id – DRK

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