Ngữ nghĩa của Có
Để hiểu rõ hơn về việc có, bạn cần xem nó từ quan điểm lý thuyết.
Một nhóm theo là truy vấn lấy bảng và tóm tắt nó thành bảng khác. Bạn tóm tắt bảng gốc bằng cách nhóm bảng gốc thành các tập con (dựa trên các thuộc tính mà bạn chỉ định trong nhóm). Mỗi nhóm trong số này sẽ mang lại một tuple.
Các Có chỉ đơn giản là tương đương với một mệnh đề WHERE sau nhóm bằng cách đã thực hiện và trước khi chọn phần của truy vấn được tính.
phép nói rằng truy vấn của bạn là:
select a, b, count(*)
from Table
where c > 100
group by a, b
having count(*) > 10;
Việc đánh giá của truy vấn này có thể được coi là các bước sau:
- Thực hiện các đề WHERE, loại bỏ hàng không đáp ứng nó.
- Nhóm bảng thành các tập con dựa trên các giá trị của a và b (mỗi bộ trong mỗi tập con có cùng giá trị a và b).
- Loại bỏ các tập hợp con không đáp ứng điều kiện HAVING
- Xử lý từng tập hợp con xuất các giá trị như được chỉ ra trong phần CHỌN của truy vấn. Điều này tạo ra một bộ dữ liệu đầu ra cho mỗi tập hợp con còn lại sau bước 3.
Bạn có thể mở rộng truy vấn phức tạp để trả về bảng (một sản phẩm chéo, tham gia, UNION, v.v.) .
Thực tế, có là syntactic sugar và không mở rộng sức mạnh của SQL. Bất kỳ truy vấn cụ thể:
SELECT list
FROM table
GROUP BY attrList
HAVING condition;
thể được viết lại như sau:
SELECT list from (
SELECT listatt
FROM table
GROUP BY attrList) as Name
WHERE condition;
Các listatt là một danh sách bao gồm GROUP BY thuộc tính và các biểu thức được sử dụng trong danh sách và điều kiện. Nó có thể là cần thiết để đặt tên một số biểu thức trong danh sách này (với AS). Ví dụ, truy vấn ví dụ trên có thể được viết lại như sau:
select a, b, count
from (select a, b, count(*) as count
from Table
where c > 100
group by a, b) as someName
where count > 10;
Các giải pháp bạn cần
giải pháp của bạn có vẻ là đúng:
SELECT s.sid, s.name
FROM Supplier s, Supplies su, Project pr
WHERE s.sid = su.sid AND su.jid = pr.jid
GROUP BY s.sid, s.name
HAVING COUNT (DISTINCT pr.jid) >= 2
Bạn tham gia ba bảng, sau đó sử dụng sid như một thuộc tính nhóm (sname phụ thuộc vào chức năng của nó, do đó nó không ảnh hưởng đến số lượng nhóm, nhưng bạn phải bao gồm nó, nếu không nó không thể là một phần của phần chọn của câu lệnh). Sau đó, bạn đang loại bỏ những thứ không thỏa mãn điều kiện của bạn: thỏa mãn pr.jid is >= 2
, điều bạn muốn ban đầu.
giải pháp tốt nhất cho vấn đề của bạn
Cá nhân tôi muốn có một giải pháp đơn giản sạch:
- Bạn cần phải nhóm chỉ bởi Vật tư (sid, pid, jid **, số lượng) để tìm sid của những người cung cấp ít nhất cho hai dự án.
- Sau đó, hãy tham gia vào bảng Nhà cung cấp để nhận được nhà cung cấp giống nhau.
SELECT sid, sname from
(SELECT sid from supplies
GROUP BY sid, pid
HAVING count(DISTINCT jid) >= 2
) AS T1
NATURAL JOIN
Supliers;
Nó cũng sẽ nhanh hơn để thực hiện, bởi vì tham gia chỉ được thực hiện khi cần thiết, không phải tất cả các lần.
--dmg
Bạn đang thiếu một 'khoản FROM' ... – plalx
có, sử dụng Ms SQL. Cảm ơn vì sự trả lời. Đối với nhiệm vụ, chúng tôi giả sử sử dụng mệnh đề GROUP BY nên tôi không chắc chắn việc viết lại nó sẽ giúp tôi. Tôi đồng ý rằng GROUP BY là khó làm theo mặc dù! – user2341124
@plalx thanks fixed.So đây là bài tập về nhà? – cbp