首先......我知道在表格中使用逗号分隔值是不好的,我不能改变它。
我有几个包含以下数据的表:
************** Table 1 **********
stock_id products_id stock_attributes
5271 279 1559,2764
************** Table 2 *********************
products_attributes_id products_id options_id options_values_id
1559 279 2 8
2764 279 3 63
************** Table 3 ************************
products_options_id products_options_name
2 Size
3 Color
************** Table 4 *****************
products_options_values_id products_options_values_name
14 Pink
63 Mint
13 Black
8 S
9 M
10 L
11 XL
我想要做的是创建一个查询,以获取表1中的字段stock_attributes,并使用表2,3和2中的信息展开它。 4所以我最终得到以下结论:
*********** Resulting Table **********
stock_id products_id opt1 opt2 opt3 opt4
5271 279 Size S Color Mint
我可以在事后以编程方式执行此操作,但我很好奇是否可以在单个SQL查询中完成。我已经找到了类似的问题和答案,如何从逗号分隔的字段中选择一个特定的值,但没有做到这一点。任何帮助表示赞赏。
答案 0 :(得分:0)
如果属性数量是固定的。您可以简单地将列拆分为多个。
SELECT stock_id, products_id,
PARSENAME(REPLACE(stock_attributes,',','.'),2) a1,
PARSENAME(REPLACE(stock_attributes,',','.'),1) a2
FROM Table1
要进一步扩展并包含其他表中的值,您可以执行简单的JOIN
select pTable.stock_id, pTable.products_id,
(select products_options_name from Table3 where products_options_id = t2.options_id) as opt1,
(select products_options_values_name from Table4 where products_options_values_id = t2.options_values_id) as opt2,
(select products_options_name from Table3 where products_options_id = t3.options_id) as opt3,
(select products_options_values_name from Table4 where products_options_values_id = t3.options_values_id) as opt4
from
(
SELECT stock_id, products_id,
PARSENAME(REPLACE(stock_attributes,',','.'),2) a1,
PARSENAME(REPLACE(stock_attributes,',','.'),1) a2
FROM Table1
) pTable
join Table2 t2 on pTable.a1 = t2.products_attributes_id and pTable.products_id = t2.products_id
join Table2 t3 on pTable.a2 = t3.products_attributes_id and pTable.products_id = t3.products_id
答案 1 :(得分:0)
这很长。所以我会停下来,直到数据准备好 Dynamic SQL Pivot
这可以解决任意数量的属性。只需将输出保存到表中o创建存储过程以获取动态数据透视的数据。
tmp: Split 以逗号分隔的行数
product_attributes
:只是一个选择来查看递归函数的结果。无法删除
product_details
:将属性与其他表连接以获取其值
product_attribute_count
:每个属性都需要row_number
,因此您可以稍后创建标题。我也意识到你不需要COUNT()
product_pre_pivot
:为option_id
和option_value_id
创建标题和值
product_pivot
:将这些对标题分隔为单个列
您可以测试每个步骤以查看结果.... SELECT * FROM [STEP#]
<强> SQL Fiddle Demo 强>
代码:
;WITH tmp([stock_id], [products_id], products_attributes_id, data_r) AS
(
SELECT
[stock_id], [products_id],
LEFT([stock_attributes], Charindex(',', [stock_attributes] + ',') - 1),
STUFF([stock_attributes], 1, Charindex(',', [stock_attributes] + ','), '')
FROM
Table1
UNION ALL
SELECT
[stock_id], [products_id],
LEFT(data_r, Charindex(',', data_r + ',') - 1),
STUFF(data_r, 1, Charindex(',', data_r + ','), '')
FROM
tmp
WHERE
data_r > ''
), product_attributes AS
(
SELECT
[stock_id], [products_id],
[products_attributes_id]
FROM
tmp
), product_details AS
(
SELECT
pa.*,
t2.options_id, t2.options_values_id,
t3.[products_options_name],
t4.[products_options_values_name]
FROM
product_attributes pa
JOIN
Table2 t2 ON pa.[products_id] = t2.[products_id]
AND pa.[products_attributes_id] = t2.[products_attributes_id]
JOIN
Table3 t3 ON t2.[options_id] = t3.[products_options_id]
JOIN
Table4 t4 ON t2.[options_values_id] = t4.[products_options_values_id]
), product_attribute_count AS
(
SELECT
*,
row_number() over (PARTITION BY products_id
ORDER BY options_id) as rn,
count(*) over (partition by products_id) cnt
FROM
product_details
), product_pre_pivot AS
(
SELECT
stock_id, products_id,
'opt' + CAST(2*rn - 1 as varchar(max)) as header1,
products_options_name as d_value,
'opt' + CAST(2*rn as varchar(max)) as header2,
products_options_values_name as a_value
FROM
product_attribute_count
), product_pivot AS
(
SELECT
stock_id, products_id,
header1 header, d_value value
FROM
product_pre_pivot
UNION ALL
SELECT
stock_id, products_id,
header2 header, a_value value
FROM
product_pre_pivot
)
SELECT *
FROM product_pivot
ORDER BY header
<强>输出强>
| stock_id | products_id | header | value |
|----------|-------------|--------|-------|
| 5271 | 279 | opt1 | Size |
| 5271 | 279 | opt2 | S |
| 5271 | 279 | opt3 | Color |
| 5271 | 279 | opt4 | Mint |