动态SQL合并垂直和水平表

问题描述 投票:1回答:3

如何构建一个SELECT,将普通表与列和值表中的数据合并?

示例:我有一个这样的客户表。

╔════════════╦═══════╦═════════╗
║ Customerid ║ name  ║ ZipCode ║
╠════════════╬═══════╬═════════╣
║          1 ║ peter ║    3030 ║
║          2 ║ Hans  ║    4040 ║
╚════════════╩═══════╩═════════╝

我想要的是这个:

╔════════════╦═══════╦═════════╦═══════════╦═══════════╗
║ Customerid ║ name  ║ ZipCode ║ AccountNr ║ CarNumber ║
╠════════════╬═══════╬═════════╬═══════════╬═══════════╣
║          1 ║ peter ║    3030 ║ jb-31234  ║ YSS-41    ║
║          2 ║ Hans  ║    4040 ║ jb-32234  ║ ABS-21    ║
╚════════════╩═══════╩═════════╩═══════════╩═══════════╝

列accountNr和车号在列对应的列和值表中。

    COLUMN TABLE
╔═════════════════════╦═════════════╗
║ customer_column_id  ║ column_name ║
╠═════════════════════╬═════════════╣
║                   1 ║ AccountNr   ║
║                   2 ║ CarNumber   ║
╚═════════════════════╩═════════════╝


    VALUE TABLE
╔════╦════════════╦══════════╦════════════════════╗
║ ID ║ customerid ║  value   ║ customer_column_id ║
╠════╬════════════╬══════════╬════════════════════╣
║  1 ║          1 ║ jb-31234 ║                  1 ║
║  2 ║          1 ║ YSS-41   ║                  2 ║
║  3 ║          2 ║ jb-32234 ║                  1 ║
║  4 ║          2 ║ ABS-21   ║                  2 ║
╚════╩════════════╩══════════╩════════════════════╝

编辑:SELECT语句postgres中的动态列的答案不是同一个问题。这个问题是如何从动态列生成数据。这很简单,可以通过一些答案来完成,也可以通过我之前使用的prosgres中的交叉表函数来完成。我的问题中的核心问题是我有一个水平(正常)表和2个垂直表,需要将它们合并为1,这样第一个表在视图模式下有更多列。

sql postgresql dynamic
3个回答
1
投票

试试这个

这里table1表示你的第一个表,VT表示值表,CV表示Column表

select  customerid,Name, value.vl as AccountNr, cvalue.cv as carnumber 
    from    table1
    /*Acount number*/
    left join
    (
    select  customerid,customer_column_id,value as vl
    from    table1
    left join VT as p 
        on  
    p.customerid=table1.customerid
    left join CT as f 
        on  
    f.Customer_column_id=p.Customer_column_id
        and where customer_column_id='1'
    ) as value 
        on  value.customerid=table1.customerid
    /*Car number*/
    left join
    (
    select  customerid,customer_column_id,value as cv
    from    table1
    left join VT as p 
        on  
    p.customerid=table1.customerid
    left join CT as f 
        on  
    f.Customer_column_id=p.Customer_column_id
        and where customer_column_id='2'
    ) as cvalue 
        on  value.customerid=table1.customerid
    group by    customerid,customer_column_id,accountno,carnumber

执行此操作并告诉我输出,因为我没有运行它。取决于你的输出我可以做一些改变


0
投票

这就是我最终的结果。它超级快。这是我的一个朋友代码,我给予了所有的信任,我做了改变。

这是做什么的。它创建一个视图,其中第一部分是customer表。

LEFT OUTER JOINS是动态部分。所以,想象一下,我首先从列表中获取列名,迭代它们并创建动态SQL,添加列名及其值。

最后一部分是“给我看”部分。由于可能有1.000.000.000行,因此不会进入普通的网络服务器。所以ROW_NUMBER给出了我需要的行。它可以是分页的一部分,例如第7-9页,其中每行有100行。

 //EXAMPLE OF TOTAL PART
            string SQL = @"  WITH tmp__View AS(select * from customer as cust_tbl
              LEFT OUTER JOIN(SELECT Value AS accountNumber, customer_id
                FROM col_extra_val  WHERE customer_column_id = 20) AS KeyTable1 ON KeyTable1.customer_id = cust_tbl.customer_id
            LEFT OUTER JOIN(SELECT Value AS lala, customer_id
                  FROM col_extra_val  WHERE customer_column_id = 19) AS KeyTable2 ON KeyTable2.customer_id = cust_tbl.customer_id
             order by cust_tbl.customer_id
            )
            SELECT* from
            (SELECT *, ROW_NUMBER() OVER(ORDER BY accountNumber DESC) As tmp__RowNumber FROM tmp__View) As tmp__TestTable
            WHERE tmp__RowNumber BETWEEN  700 AND   900;"

0
投票

如果您可以选择在sql之外构建查询,那么我建议按照以下方式进行操作

SELECT
  'SELECT c.Customerid, c.name, c.ZipCode, ' ||
  string_agg(
    'vt' || ct.customer_column_id || '.value AS ' || ct.column_name,
    ', ')
  || ' FROM customers c ' ||
  string_agg(
    ' LEFT JOIN value_table vt' || ct.customer_column_id || ' ON ' ||
    'vt' || ct.customer_column_id || '.customer_column_id = ' || ct.customer_column_id ||
    ' AND vt' || ct.customer_column_id || '.customerid = c.Customerid',
    ' ')
  || ' ORDER BY c.Customerid DESC '
  || ' OFFSET 0 LIMIT 100;'
FROM column_table ct;

结果将是您的“动态”列的查询

SELECT
    c.Customerid,
    c.name,
    c.ZipCode,
    vt1.value AS AccountNr,
    vt2.value AS CarNumber
FROM customers c
    LEFT JOIN value_table vt1 ON vt1.customer_column_id = 1 AND vt1.customerid = c.Customerid
    LEFT JOIN value_table vt2 ON vt2.customer_column_id = 2 AND vt2.customerid = c.Customerid
ORDER BY c.Customerid DESC
OFFSET 0 LIMIT 100;
© www.soinside.com 2019 - 2024. All rights reserved.