SQL多对一枢轴

时间:2017-09-13 13:57:36

标签: mysql

给出如此数据结构:

CREATE TABLE records (
  id INT PRIMARY KEY AUTO_INCREMENT, 
  name VARCHAR(255) NOT NULL
);

CREATE TABLE records_data (
  id INT PRIMARY KEY AUTO_INCREMENT,
  record_id INT NOT NULL,
  record_data_type_id INT NOT NULL,
  data VARCHAR(255),
  UNIQUE(record_id, record_data_type_id)
);

CREATE TABLE records_data_types (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL UNIQUE
);

和(样本)数据如下:

INSERT INTO records_data_types (name) VALUES ('Location');
INSERT INTO records_data_types (name) VALUES ('Ice Cream Flavor');
INSERT INTO records_data_types (name) VALUES ('Slogan');
INSERT INTO records_data_types (name) VALUES ('Starting Pay');
INSERT INTO records_data_types (name) VALUES ('Grand Opening Date');

INSERT INTO records (name) VALUES ('Business A');
INSERT INTO records (name) VALUES ('Business B');
INSERT INTO records (name) VALUES ('Business C');
INSERT INTO records (name) VALUES ('Business D');

INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (1, 1, 'New York, NY');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (1, 2, 'Chocolate');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (1, 3, 'The only apple!');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (1, 4, '27');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (1, 5, '2017-09-01');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (2, 1, 'Chicago, IL');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (2, 2, 'Vanilla');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (2, 3, 'Windy and tasty');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (2, 4, '10');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (2, 5, '2017-01-01');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (3, 1, 'Seattle, WA');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (3, 2, 'Rocky Road');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (3, 5, '2011-05-14');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (4, 2, 'Mint Chip');
INSERT INTO records_data (record_id, record_data_type_id, data) VALUES (4, 3, 'Toothpaste and orange juice');

(Here's a db-fiddle)

我希望获得一个透视结果集,其中列标题为records_data_types.name,每行都属于record条目。

对于每个条目,我希望得到:

SELECT 
  records.name as RecordName,
  records_data_types.name as DataType,
  records_data.data as Data
FROM records_data
  INNER JOIN records 
    ON records_data.record_id = records.id
  INNER JOIN records_data_types 
    ON records_data_types.id=records_data.record_data_type_id
WHERE records.id = ? -- for each record, pivoted;

这些数据是由代码处理的(在这种情况下是PHP,但它并不重要,所以使用该查询来收集数据,然后使用代码将结果集配置为记录与数据关系的记录数组。

我正在使用MySQL和SQL Server(2005),并且已经将PIVOT运算符与SQL服务器一起使用,但这会导致性能下降(这是一个相当庞大的数据库)。

这里主要关注的是我绝对可以将每个记录作为子查询获取,但最终(并且在实际生产情况下)使用10-20个数据项拉出更大的记录集(可能是300多条记录)会产生非常大的数量数据(3000-6000 +行)。

似乎最快的查询只是执行左连接,并通过代码格式化数据。子查询似乎是第二个(参见DB-Fiddle

通过查看SO和其他地方的其他类似问题,似乎有很多方法可以使用PIVOT运算符,使用公共表表达式,临时表和/或子查询来执行此调整,但大多数依赖于在枢轴中的聚合(即通过max(数据)转动),但在这种情况下,它只是一对一的关系。对于任何一条记录,每种数据类型只有一个数据条目。

TLDR:有更好的方法可以优化this等查询吗?

谢谢!

0 个答案:

没有答案