简体   繁体   English

SQL计数在我的INNER JOIN语句中返回错误的值

[英]SQL Count returns wrong value in my INNER JOIN Statement

I am quite new to SQL and I am having some difficulty with my COUNT() feature. 我对SQL还是很陌生,并且在使用COUNT()功能时遇到了一些困难。

It keeps returning the wrong COUNT() value as I am trying to calculate the TOTAL number of specific cars sold by users. 当我试图计算用户出售的特定汽车的TOTAL时,它一直返回错误的COUNT()值。 My tables and results are here: http://sqlfiddle.com/#!9/d2ef0/5 我的表格和结果在这里: http : //sqlfiddle.com/#!9/d2ef0/5

My Schema: 我的架构:

CREATE TABLE IF NOT EXISTS Users(
    userID INT NOT NULL AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    forename VARCHAR(50) NOT NULL,
    surname VARCHAR(50) NOT NULL,
    PRIMARY KEY (userID)
);

CREATE TABLE IF NOT EXISTS CarType(
    carTypeID INT NOT NULL AUTO_INCREMENT,
    description VARCHAR(80),
    PRIMARY KEY (carTypeID)
);  

CREATE TABLE IF NOT EXISTS Country(
    countryID INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(100),
    PRIMARY KEY (countryID)
);  

CREATE TABLE IF NOT EXISTS Cars(
    carID INT NOT NULL AUTO_INCREMENT,
    carTypeID INT NOT NULL,
    countryID INT NOT NULL,
    description VARCHAR(100) NOT NULL,
    make VARCHAR(100) NOT NULL,
    model VARCHAR(100),
    FOREIGN KEY (carTypeID) REFERENCES CarType(carTypeID),
    FOREIGN KEY (countryID) REFERENCES Country(countryID),
    PRIMARY KEY (carID)
);

CREATE TABLE IF NOT EXISTS Likes(
    userID INT NOT NULL,
    carID INT NOT NULL,
    likes DOUBLE NOT NULL,
    FOREIGN KEY (userID) REFERENCES Users(userID),
    FOREIGN KEY (carID) REFERENCES Cars(carID)
);

CREATE TABLE IF NOT EXISTS Sold(
    userID INT NOT NULL,
    carID INT NOT NULL,
    FOREIGN KEY (userID) REFERENCES Users(userID),
    FOREIGN KEY (carID) REFERENCES Cars(carID)
);

INSERT INTO Users VALUES 
(NULL, "micheal", "Micheal", "Sco"),
(NULL, "bensco", "Ben", "Sco"),
(NULL, "shanemill", "Shane", "Miller");

INSERT INTO CarType VALUES
(NULL, "Saloon"),
(NULL, "HatchBack"),
(NULL, "Low Rider");

INSERT INTO Country VALUES
(NULL, "UK"),
(NULL, "USA"),
(NULL, "JAPAN"),
(NULL, "GERMANY");

INSERT INTO Cars VALUES
(NULL, 1, 2, "Ford Mustang lovers", "Mustang", "Ford"),
(NULL, 2, 3, "Drift Kings", "Skyline", "Nissan"),
(NULL, 3, 1, "British classic", "Cooper", "Mini");

INSERT INTO Likes VALUES
(1, 1, 3),
(1, 2, 2),
(2, 3, 5),
(2, 3, 7),
(2, 3, 1),
(2, 3, 2);

INSERT INTO Sold VALUES
(1, 2),
(1, 3),
(1, 1),
(2, 2),
(2, 3),
(3, 1),
(3, 3);

This is the Sold table: 这是Sold表:

userID  carID
  1      2
  1      3
  1      1
  2      2
  2      3
  3      1
  3      3

This is my complex query: 这是我的复杂查询:

SELECT DISTINCT Cars.carID, Cars.description, Cars.model, Country.name, 
CarType.description, ROUND(AVG(Likes.likes)), COUNT(*)
FROM Cars
INNER JOIN Sold ON
Cars.carID = Sold.carID
INNER JOIN Country ON
Cars.countryID = Country.countryID
INNER JOIN CarType ON
Cars.carTypeID = CarType.carTypeID
INNER JOIN Likes ON
Cars.carID = Likes.carID
GROUP BY Cars.carID

The actual result from this complex SQL Query : 此复杂的SQL Query的实际结果:

carID   description             model       name    description     ROUND(AVG(Likes.likes))     COUNT(*)
1       Ford Mustang lovers     Ford        USA     Saloon              3                           2
2       Drift Kings             Nissan      JAPAN   HatchBack           2                           2
3       British classic         Mini        UK      Low Rider           4                           12

For example, the result for the last one is incorrect - it should not be 12 例如,最后一个的结果不正确-不应为12

Would be nice if someone could tell me where I went wrong 如果有人能告诉我我哪里出问题了,那会很好

Thanks 谢谢

You are attempting to aggregate across two different dimensions -- Sold and Likes . 您试图跨两个不同维度进行汇总- Sold和点Likes The result is a Cartesian product of rows for each car, and this throws off the aggregations. 结果是每个汽车的行的笛卡尔积,这将引发聚合。

The solution is the pre-aggregate the results along each dimension: 解决方案是预先汇总各个维度上的结果:

SELECT c.carID, c.description, c.model, cy.name, ct.description,
       l.avgLikes, s.NumSold
FROM Cars c INNER JOIN
     (SELECT s.CarId, COUNT(*) as NumSold
      FROM Sold s
      GROUP BY s.CarId
     ) s
     ON c.carID = s.carID INNER JOIN
     Country cy
     ON c.countryID = cy.countryID INNER JOIN
     CarType ct
     ON c.carTypeID = ct.carTypeID LEFT JOIN
     (SELECT l.carId, AVG(Likes) as avgLikes
      FROM Likes l
      GROUP BY CarId
     ) l
     ON c.carID = l.carID;

Here is the SQL Fiddle. 是SQL Fiddle。

If all you want is the total number of specific cars sold by user then all your info is in the sold table. 如果您想要的只是用户出售的特定汽车的总数,那么您的所有信息都在已出售的表格中。 This query will give you what you want by carID. 该查询将通过carID给您您想要的东西。 You can use that as a subquery if you want to join on other tables to get more info. 如果要加入其他表以获取更多信息,可以将其用作子查询。

SELECT userID, carID, count(*) as totalSold FROM Sold GROUP BY userID, carID;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM