Sql 在定义存在的地方合并
我这里有三张桌子<代码>属性映射,Sql 在定义存在的地方合并,sql,tsql,Sql,Tsql,我这里有三张桌子属性映射,组定义,以及组映射 ATTRIBUTE\u MAP包含CUST\u ID和相关的ATTRIBUTE\u ID GROUP\u定义定义一个组。其列为组ID,属性1,值1,属性2,值2,属性3,值3组由1到3个带值的属性组成。例如,属性可以是“State”,其值为“newyork”。对于“Owns Car”等布尔值,值也可以为null GROUP\u MAP只需将CUST\u ID映射到GROUP\u ID 现在,我正在尝试编写一个脚本,查看属性映射,查看客户是否属于组定义
组定义
,以及组映射
ATTRIBUTE\u MAP
包含CUST\u ID
和相关的ATTRIBUTE\u ID
GROUP\u定义
定义一个组。其列为组ID
,属性1
,值1
,属性2
,值2
,属性3
,值3
组由1到3个带值的属性组成。例如,属性可以是“State”,其值为“newyork”。对于“Owns Car”等布尔值,值也可以为null
GROUP\u MAP
只需将CUST\u ID
映射到GROUP\u ID
现在,我正在尝试编写一个脚本,查看属性映射
,查看客户是否属于组定义
中定义的组之一。如果他(客户)这样做,则使用CUST\u ID
和GROUP\u ID
在GROUP\u MAP
中插入/更新一行。我遇到问题的部分是匹配属性值
以下是我到目前为止的情况:
merge GROUP_MAP gm using
( select am.CUST_ID
,am.ATTRIBUTE_ID
,am.START_DATE
,gd.GROUP_ID
,gd.ATTRIBUTE_1
,gd.VALUE_1
,gd.ATTRIBUTE_2
,gd.VALUE_2
,gd.ATTRIBUTE_3
,gd.VALUE_3
from ATTRIBUTE_MAP am, GROUP_DEFINITIONS gd ) src
on gm.GROUP_ID=src.GROUP_ID
AND gm.CUST_ID=src.CUST_ID
when not matched then -- create association in GROUP_MAP
insert (CUST_ID, GROUP_ID, FROM_DATE)
values (src.CUST_ID, src.GROUP_ID, src.START_DATE);
我的做法正确吗?我想我需要改进合并中的嵌套select语句,以加入属性映射和对等组定义,然后从那里开始。如有任何帮助/建议,将不胜感激
以下是一个供参考的示例:
属性映射
:
+---------+--------------+------------+
|客户ID |属性ID |值|
+---------+--------------+------------+
|50 | 1 |“纽约”|
+---------+--------------+------------+
| 50 | 2 | |
+---------+--------------+------------+
组定义
:
+----------+-------------+------------+-------------+---------+-------------+---------+
|组ID |属性|值|值| 1 |属性|值|值|值| 3|
+----------+-------------+------------+-------------+---------+-------------+---------+
|10 | 1 |纽约| 2 | ||
+----------+-------------+------------+-------------+---------+-------------+---------+
| 20 | 2 | | | | | |
+----------+-------------+------------+-------------+---------+-------------+---------+
因此脚本应该生成(在组映射中):
+---------+----------+--------+
|客户ID |集团ID |日期|
+---------+----------+--------+
|50 | 10 |*日期*|
+---------+----------+--------+
|50 | 20 |*日期*|
+---------+----------+--------+
我可以完全关闭,但看起来您的内部选择应该是这样的。如果我理解您试图执行的操作,这将返回一个唯一的CUST_ID、GROUP_ID、START_DATE列表,其中所有客户属性与所有组属性匹配。只是写得这么快,所以可能会有一些错误,但它可能会让你走上正确的方向
with gd as (
SELECT GROUP_ID, ATTRIBUTE_1 as ATTRIBUTE_ID, VALUE_1 as VALUE from GROUP_DEFINITIONS
UNION
SELECT GROUP_ID, ATTRIBUTE_2, VALUE_2 from GROUP_DEFINITIONS
UNION
SELECT GROUP_ID, ATTRIBUTE_3, VALUE_3 from GROUP_DEFINITIONS
)
MERGE GROUP_MAP gm
USING
(
SELECT am.CUST_ID, gd.GROUP_ID, am.START_DATE
FROM ATTRIBUTE_MAP am
JOIN gd
ON am.ATTRIBUTE_ID = gd.ATTRIBUTE_ID AND coalesce(am.VALUE, '') = coalesce(gd.VALUE, '')
join (select GROUP_ID, count(*) as ATTR_COUNT from gd where ATTRIBUTE_ID is NOT NULL group by GROUP_ID) as gc
on gd.GROUP_ID = gc.GROUP_ID
GROUP BY am.CUST_ID, gd.GROUP_ID, am.START_DATE
HAVING count(am.ATTRIBUTE_ID) = max(gc.ATTR_COUNT)
) src
ON gm.GROUP_ID = src.GROUP_ID
AND gm.CUST_ID = src.CUST_ID
WHEN NOT MATCHED
THEN -- create association in GROUP_MAP
INSERT(CUST_ID,
GROUP_ID,
FROM_DATE) VALUES
(src.CUST_ID, src.GROUP_ID, src.START_DATE);
如果我正确理解了问题,这应该可以做到:
请注意,我使用了GETDATE()
,因为我没有[START\u DATE]字段,但您需要在代码中替换它
样本数据:
CREATE TABLE #ATTRIBUTE_MAP(CUST_ID INT,
ATTRIBUTE_ID INT,
VALUE VARCHAR(20));
INSERT INTO #ATTRIBUTE_MAP
VALUES
(50, 1, 'New York'),
(50, 2, NULL);
CREATE TABLE #GROUP_DEFINITIONS(GROUP_ID INT,
ATTRIBUTE_1 INT,
VALUE_1 VARCHAR(20),
ATTRIBUTE_2 INT,
VALUE_2 VARCHAR(20),
ATTRIBUTE_3 INT,
VALUE_3 VARCHAR(20));
INSERT INTO #GROUP_DEFINITIONS
VALUES
(10, 1, 'New York', 2, NULL, NULL, NULL),
(20, 2, NULL, NULL, NULL, NULL, NULL);
CREATE TABLE #GROUP_MAP(CUST_ID INT,
GROUP_ID INT,
[FROM_DATE] DATE);
查询:
MERGE #GROUP_MAP gm
USING
(SELECT DISTINCT
am.CUST_ID,
CAST(GETDATE() AS DATE) AS [START_DATE], --<-- you will need to change this
gd.GROUP_ID
FROM #ATTRIBUTE_MAP am
INNER JOIN
(
SELECT GROUP_ID,
ATTRIBUTE_1 AS ATTRIBUTE_ID,
VALUE_1
FROM #GROUP_DEFINITIONS
UNION ALL
SELECT GROUP_ID,
ATTRIBUTE_2,
VALUE_2
FROM #GROUP_DEFINITIONS
UNION ALL
SELECT GROUP_ID,
ATTRIBUTE_3,
VALUE_3
FROM #GROUP_DEFINITIONS) gd ON am.ATTRIBUTE_ID = gd.ATTRIBUTE_ID) src
ON gm.GROUP_ID = src.GROUP_ID
AND gm.CUST_ID = src.CUST_ID
WHEN NOT MATCHED
THEN -- create association in GROUP_MAP
INSERT(CUST_ID,
GROUP_ID,
FROM_DATE) VALUES
(src.CUST_ID, src.GROUP_ID, src.START_DATE);
结果:
您能解释一下属性映射和组之间的关系吗_DEFINITIONS@KamranFarzami两者之间确实没有直接关系。属性映射将离散的属性/值映射到客户,而组定义更像是一个维度表-它只用于定义一个组。这有意义吗?属性映射记录必须匹配组定义记录中的所有属性,还是仅匹配其中的任何一个?是一个空的组\u定义。属性\ux]值为空,还是一个空字符串?am.START\u DATE的值是您需要考虑的,它是什么类型的。是日期还是日期时间。GROUP_MAP中的列DATE只是记录插入GROUP_MAP表时的时间戳?@radshop空属性为NULL。属性映射记录仅包含1个客户与1个属性的关联。如果客户有多个属性,则它们是单独的记录。如果分配给客户的属性满足组中的所有属性“条件”,则该客户将属于一个组。我可能错了,但在我看来,如果某些属性(但不是所有属性)匹配,则这将不正确地匹配客户和组。您的示例数据没有这种情况。@radshop请您完成以下内容并回复给我,我将测试您提到的情况:插入到#GROUP#u定义值(,,,)插入到#GROUP#u定义值(30,1,'纽约',5,'面包店',NULL,NULL)我明白您的意思,但从某种意义上说,它仍然是正确的,因为我们在该组中还有属性_1=1和值_1='newyork'。我只是使用@KamranFarzami中的设置代码来测试这个,它不起作用(开始时很匆忙),我现在没有时间处理它。我会稍后再查看。修复并测试了代码。我想它能满足你的需求。到目前为止,它似乎还在工作。我对语法有点困惑。为什么我们需要在这里合并:coalesce(am.VALUE,”)=coalesce(gd.VALUE,”)
?@Ted您显示的示例数据具有空值,因此为了匹配这些值,我们将它们合并为一个空的非空值。拿出联合体,看看有什么不同——也许我误解了你的要求,所以不管用什么都可以。
SELECT CUST_ID , GROUP_ID , FROM_DATE
FROM #GROUP_MAP;