【问题标题】:SQL Count returns wrong value in my INNER JOIN StatementSQL Count 在我的 INNER JOIN 语句中返回错误值
【发布时间】:2016-02-29 00:53:26
【问题描述】:

我对 SQL 还很陌生,我在使用 COUNT() 功能时遇到了一些困难。

当我试图计算用户销售的特定汽车的TOTAL 数量时,它不断返回错误的COUNT() 值。我的表格和结果在这里: http://sqlfiddle.com/#!9/d2ef0/5

我的架构:

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);

这是Sold 表:

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

这是我的复杂查询:

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

这个复杂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

例如,最后一个的结果不正确 - 它不应该是12

如果有人能告诉我哪里出错了就太好了

谢谢

【问题讨论】:

  • 您应该在实际问题中包含您的查询和原始表数据。至少包含足够的信息以使您的问题可重现。
  • 好的,我会添加它 - 请给我一分钟
  • 我认为您应该在联接中排除 LIKES 表,因为它与 SOLD 的结构基本相同,并且您刚刚添加了列 likes 这会影响您的结果 COUNT()
  • 已编辑,请参阅 OP

标签: sql database count


【解决方案1】:

您正尝试跨两个不同的维度进行聚合——SoldLikes。结果是每辆车的行的笛卡尔积,这会抛出聚合。

解决方案是对每个维度的结果进行预聚合:

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 是 SQL Fiddle。

【讨论】:

  • 非常感谢伙计。它有效,我想我在这里学到了一些新东西
【解决方案2】:

如果您想要的只是用户销售的特定汽车的总数,那么您的所有信息都在售出表中。此查询将通过 carID 为您提供所需的内容。如果您想加入其他表以获取更多信息,可以将其用作子查询。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多