如何构建一个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,这样第一个表在视图模式下有更多列。
试试这个
这里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
执行此操作并告诉我输出,因为我没有运行它。取决于你的输出我可以做一些改变
这就是我最终的结果。它超级快。这是我的一个朋友代码,我给予了所有的信任,我做了改变。
这是做什么的。它创建一个视图,其中第一部分是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;"
如果您可以选择在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;