使用min,max和condition从SQL获取结果

Gac*_*cci 7 mysql

我正在尝试学习一些(先进的或更复杂的)SQL.
假设我有一张汽车的桌子,上面有每辆车的信息.
然后我有另一张桌子,有车出售,有些是新的,有些是用的.

我希望用户能够查看汽车,例如本田思域2016,并查看汽车信息.
但也希望用户看到所有本田思域2016款车型的销售情况,包括特定年份/车型的最高价和最低价,由新车和二手车组织.

什么是最有效的方式来检索所有信息 - 汽车信息和出售在页面上显示的信息!

这些是我的表.

CREATE TABLE Users(
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(16) NOT NULL,
    last VARCHAR(16) NOT NULL,
    email VARCHAR(128) NOT NULL,
    phone CHAR(10) NOT NULL,
    joined DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE Cars(
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    make VARCHAR(32) NOT NULL,
    model VARCHAR(32) NOT NULL,
    year INT(4) NOT NULL,
    trim VARCHAR(16) NOT NULL
);

CREATE TABLE Market(
    id BIGINT(20) NOT NULL AUTO_INCREMENT,
    user_id BIGINT(20) NOT NULL,
    car_id BIGINT(20) NOT NULL,
    condition VARCHAR(5) NOT NULL,
    notes VARCHAR(1024) NOT NULL,
    PRIMARY KEY(id),

    CONSTRAINT cfk FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT ufk FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
);
Run Code Online (Sandbox Code Playgroud)

它对我来说看起来多余,随着桌子越来越大,注定会变慢.如果有人向我展示更好的方式,我将不胜感激.

/* Get car information*/
SELECT *
FROM Cars 
WHERE make = 'Honda' 
  AND model = 'Civic' 
  AND year = '2017'   
  AND trim = 'EX'; 

/* I also would like to get the min and max price for this particular car*/
/* ?? How ?? */

/* Get (new) cars being sold and sellers */
SELECT M.*, U.* 
FROM Market M 
INNER JOIN Users ON M.user_id = U.id 
WHERE make = 'Honda' 
  AND model = 'Civic' 
  AND year = '2017' 
  AND color = 'white' 
  AND trim = 'EX' 
  AND condition = 'NEW';

/* Get (used) cars being sold and sellers */
SELECT M.*, U.* 
FROM Market M 
INNER JOIN Users ON M.user_id = U.id 
WHERE make = 'Honda' 
  AND model = 'Civic' 
  AND year = '2017' 
  AND color = 'white' 
  AND trim = 'EX' 
  AND condition = 'USED';
Run Code Online (Sandbox Code Playgroud)

我最终希望使用PHP获得类似下面的内容:

{
    car: {
        make: "Honda",
        model: "Civic",
        year: 2017,
        trim: "EX"
    },
    market: {
        new: {
            min: 'overall min',
            max: 'overall max',
            data: [{
                seller:{
                    name: "John",
                    last: "Smith",
                    phone: "xxx-xxx-xxxx",
                    email: "email@domain.com",
                },
                car: {
                    price: 15000,
                    color: "white",
                    condition: "used",
                    notes: "Some notes about the car"
                }
            }]
        },
        used: { 
            min: 'overall min',
            max: 'overall max',
            data: [{
                seller:{
                    name: "John",
                    last: "Smith",
                    phone: "xxx-xxx-xxxx",
                    email: "email@domain.com",
                },
                car: {
                    price: 15000,
                    color: "white",
                    condition: "new",
                    notes: "Some notes about the car"
                }
            }]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦我检索到信息,我就可以使用这种格式.此外,我将不得不通过数据库分页.

基本上我有兴趣了解做亚马逊的最佳方式.一件商品可以从不同的供应商处以不同的价格出售.亚马逊提供有关待售物品的信息; 它的条件,价格,卖方等.此外,亚马逊为您提供最低,最高价格和一般项目的信息.什么是最好的方法?

Jos*_*ber 6

四个查询应该没问题:

  • 一个查询,以获取有关汽车类型的一般信息
  • 另一个通过条件获得最小/最大价格的查询
  • 然后查询每个以获取新的和使用的可用汽车的市场列表.您可以懒洋洋地进行这两个查询 - 首先向您的购物者显示基本的汽车信息和最小/最大新/使用价格,然后当您的购物者点击使用过的号码(如亚马逊)时,获取二手车的市场报价.

对于最小/最大销售额,您需要进行聚合,GROUP BY您的朋友也是如此.试试这个:

SELECT `condition`, MIN(price) min_price, MAX(price) max_price
FROM Cars
JOIN Market ON (Cars.id = Market.car_id)
WHERE make = 'Honda'
  AND model = 'Civic'
  AND year = '2017'
  AND trim = 'EX'
GROUP BY `condition`; 
Run Code Online (Sandbox Code Playgroud)

您的其他查询看起来不错.随着表的增长以及您希望快速保持查询,索引将有所帮助.基本规则是作为WHERE谓词一部分的字段很适合编制索引.JOIN表之间的任何键通常都可以编入索引.尝试使用索引Cars(make, model, year, trim).

此外,condition是MySQL 5.7中的保留字,这就是我使用反引号转义的原因.请考虑使用cond,如果您只有几个条件{"new","used"},请考虑使用ENUM数据类型.当心MIN并且MAX还保留db字.