简体   繁体   English

SQL 主表多个左连接与键值对查找

[英]SQL Master Table multiple left joins with Key-Value Pair Look ups

Application - Legacy Enterprise System designed 20 yrs back应用程序 - 20 年前设计的旧企业系统

I have a Product table with 50+ Rows where each column is an attribute, like我有一个包含 50 多行的产品表,其中每一列都是一个属性,例如

ID, Name, Brand, Category, Category, Gender, Item Code, Color Code......

Now most(around 43/50) of the columns have a key(or id) of the value (eg For Brand, key b02 is stored, which translates to Brown Bag Brand, Key-Value is stored in different table)现在大多数(大约 43/50)的列都有一个值的键(或 id)(例如,对于 Brand,键b02被存储,它转换为Brown Bag Brand,键值被存储在不同的表中)

This design is not exactly EAV, but different one done in a legacy application by a 3rd part application.这种设计不完全是 EAV,而是由第三部分应用程序在遗留应用程序中完成的不同设计。

We are trying to get the data out of the DB into more Report/Analytics Friendly Format where-by I join each key based column in Master Table with Key-Value (using left join) and arrive at final table and store in different DB for Reporting.我们正在尝试将数据从数据库中提取为更多的报告/分析友好格式,其中我将主表中的每个基于键的列与键值(使用左连接)连接起来,并到达最终表并存储在不同的数据库中报告。

This is working fine for smaller set, but if the data is large (>20K Rows), its getting slow as there are too many left joins这适用于较小的集合,但如果数据很大(> 20K 行),由于左连接太多,它会变慢

I see no option other than this approach, but if any one can give me more ideas to make it more efficient and fast, it will be helpful.除了这种方法,我看不到其他选择,但是如果有人能给我更多想法以使其更高效和快速,那将很有帮助。

SELECT Product.id, Product.name, s1.value as 'Brand', s2.value as 'Category'
  , s3.value as 'Gender'
FROM Product
LEFT JOIN Attribute s1 ON s1.id = Product.brand AND s1.attribute = 'brand'
LEFT JOIN Attribute s2 ON s2.id = Product.category AND s2.attribute = 'category'
LEFT JOIN Attribute s3 ON s3.id = Product.gender AND s3.attribute = 'gender'

... 40 more

One way that will probably improve this query's performance is to use conditional aggregation instead of multiple joins:一种可能会提高此查询性能的方法是使用条件聚合而不是多个连接:

SELECT   P.id
        ,P.name
        ,MAX(CASE WHEN A.Id = P.brand AND A.attribute = 'brand' THEN A.value END) as 'Brand'
        ,MAX(CASE WHEN A.Id = P.category AND A.attribute = 'category' THEN A.value END) as 'Category'
        ,MAX(CASE WHEN A.Id = P.gender AND A.attribute = 'gender' THEN A.value END) as 'Gender'
        -- 40 more
FROM Product As P
LEFT JOIN Attribute As A
    ON A.id IN(P.brand, P.category, P.gender /* 40 more */) 
    AND A.attribute IN('brand', 'category', 'gender' /* 40 more */)    
-- The group by clause must contain all the columns that are not translated using the attribute table
GROUP BY P.id, P.name

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

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