Как бы я написал этот 3-х уровневый запрос MySQL? - PullRequest
3 голосов
/ 15 октября 2008

Это может быть немного сложно объяснить, но я постараюсь.

Я хочу отобразить список категорий (хранящихся в 1 таблице) и количество доменов, связанных с каждой категорией (хранящихся в другой таблице).

Обезьяна в этом случае заключается в том, что с каждым доменом связан набор записей (которые хранятся в третьей таблице). Я хочу показать только категории, с которыми связаны домены, а количество доменов должно отражать только те домены, с которыми связаны записи (из 3-й таблицы).

Мой текущий запрос

SELECT r.rev_id, c.cat_id, c.cat_name, count(d.dom_id) As rev_id_count FROM reviews r
INNER JOIN  domains d ON r.rev_domain_from=d.dom_id 
INNER JOIN  categories c ON d.dom_catid=c.cat_id  
WHERE rev_status = 1
GROUP BY cat_name  
ORDER BY cat_name

Это выбирает правильные имена категорий, но показывает ложное количество (rev_id_count). Если в категории есть 2 домена, и в каждом домене есть 2 записи, то будет показано число 4, когда оно должно быть 2.

Ответы [ 5 ]

3 голосов
/ 15 октября 2008
SELECT Categories.Name,count(DISTINCT categories.name) FROM Categories
JOIN Domains ON Categories.ID=Domains.CID
JOIN Records ON Records.DID=Domains.ID
GROUP BY Categories.Name

Протестировано со следующей настройкой:


CREATE TABLE Categories (Name nvarchar(50), ID int  NOT NULL IDENTITY(1,1))
CREATE TABLE Domains (Name nvarchar(50), ID int NOT NULL IDENTITY(1,1), CID int)
CREATE TABLE Records (Name nvarchar(50), ID int NOT NULL IDENTITY(1,1), DID int)

INSERT INTO Records (DID) VALUES (1)
INSERT INTO Records (DID) VALUES (1)
INSERT INTO Records (DID) VALUES (2)
INSERT INTO Records (DID) VALUES (2)
INSERT INTO Records (DID) VALUES (3)
INSERT INTO Records (DID) VALUES (3)

INSERT INTO Domains (Name,CID) VALUES ('D1',1)
INSERT INTO Domains (Name,CID) VALUES ('D2',1)
INSERT INTO Domains (Name,CID) VALUES ('D5',1)
INSERT INTO Domains (Name,CID) VALUES ('D3',2)
INSERT INTO Domains (Name,CID) VALUES ('D4',2)

INSERT INTO Categories (Name) VALUES ('1')
INSERT INTO Categories (Name) VALUES ('2')
INSERT INTO Categories (Name) VALUES ('3')
2 голосов
/ 15 октября 2008
select c.name, count(distinct d.did) from domains d
  left join categories c on c.cid = d.cid
  left join records r on r.did = d.did
  group by c.name

протестировано с 2 категориями, 2 доменами на категории, случайное количество записей на домен. набор результатов:

name     count
----     -----    
test     2
test2    2
0 голосов
/ 15 октября 2008

Начните с выбора домена, в котором есть записи, а затем выберите категории, соответствующие домену.

так что-то вроде

 SELECT * FROM records 
    INNER JOIN domains on <clause> 
    INNER JOIN categories on <clause>
 WHERE <something>

Я не могу объяснить это слишком хорошо, но слишком часто при написании SQL легко смотреть на вещи из списка полей, которые мы хотим выбрать, и склонны использовать это, чтобы диктовать способ, которым мы используем таблицы для построить данные. На самом деле мы должны больше смотреть на то, как данные связаны с запросом, который мы создаем (который часто кажется задом наперед).

0 голосов
/ 15 октября 2008

Расширяясь на решение AquilaX, вам просто нужно выбрать имя домена:

SELECT c.name, d.name, count(d.id)
  FROM categories c
    JOIN domains d ON c.id = d.cid
    JOIN records r ON r.did = d.id
GROUP BY c.name, d.name;

Что должно показать:

Cat 1, Domain 1, 2
Cat 1, Domain 2, 1
Cat 2, Domain 3, 5

и т.д ...

(но не проверено)

0 голосов
/ 15 октября 2008

Как то так?

SELECT c.name, count(d.id)
FROM categories c
JOIN domains d ON c.id = d.cid
JOIN records r ON r.did = d.id
GROUP BY c.name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...