SQL 查询从其他列上的表和组中选择

发布于 2024-10-17 22:47:17 字数 494 浏览 1 评论 0原文

我对问题标题的措辞很糟糕,因为我不确定如何称呼我想要做的事情,但它确实应该很简单。

我有一个包含两个 ID 列的链接/连接表。我想在将新行保存到表之前运行检查。

用户可以通过网页保存属性,但我需要在保存之前检查相同的组合是否不存在。对于一条记录,很容易,显然您只需检查该 attributeId 是否已在表中,如果是,则不允许他们再次保存它。

但是,如果用户选择该属性和另一属性的组合,则应允许他们保存它。

这是我的意思的图像:

在此处输入图像描述

因此,如果用户现在尝试保存 ID 为 1 的属性它会阻止他们,但如果他们尝试 ID 为 1、10,只要 1 和 10 具有相同的 ProductAttributeId,我也需要它来阻止他们。

我在解释中对此感到困惑,但我希望该图像能够澄清我需要做什么。

这应该很简单,所以我想我错过了一些东西。

I'm phrasing the question title poorly as I'm not sure what to call what I'm trying to do but it really should be simple.

I've a link / join table with two ID columns. I want to run a check before saving new rows to the table.

The user can save attributes through a webpage but I need to check that the same combination doesn't exist before saving it. With one record it's easy as obviously you just check if that attributeId is already in the table, if it is don't allow them to save it again.

However, if the user chooses a combination of that attribute and another one then they should be allowed to save it.

Here's an image of what I mean:

enter image description here

So if a user now tried to save an attribute with ID of 1 it will stop them, but I need it to also stop them if they tried ID's of 1, 10 so long as both 1 and 10 had the same productAttributeId.

I'm confusing this in my explanation but I'm hoping the image will clarify what I need to do.

This should be simple so I presume I'm missing something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦与时光遇 2024-10-24 22:47:17

如果我正确理解了这个问题,您希望防止重复使用 AttributeIdProductAttributeId 的组合。如果是这种情况,只需将它们设置为组合主键,这本质上是唯一

如果这不可行,请创建一个存储过程,针对 AttributeId 实例的联接运行查询。如果查询返回 0 个实例,则插入该行。

这里有一些简单的代码来展示这个想法(可能需要修改才能与您的数据库一起使用):

SELECT COUNT(1) FROM MyJoinTable WHERE AttributeId = @RequestedID
IF @@ROWCOUNT = 0
BEGIN
   INSERT INTO MyJoinTable ...
END

If I understand the question properly, you want to prevent the combination of AttributeId and ProductAttributeId from being reused. If that's the case, simply make them a combined primary key, which is by nature UNIQUE.

If that's not feasible, create a stored procedure that runs a query against the join for instances of the AttributeId. If the query returns 0 instances, insert the row.

Here's some light code to present the idea (may need to be modified to work with your database):

SELECT COUNT(1) FROM MyJoinTable WHERE AttributeId = @RequestedID
IF @@ROWCOUNT = 0
BEGIN
   INSERT INTO MyJoinTable ...
END
过度放纵 2024-10-24 22:47:17

您可以通过存储过程控制插入。我的理解是

  1. 用户可以选择属性的组合,例如
    • 只有1
    • 1 和 10 在一起
    • 1,4,5,10(4 个属性)

这些需要作为针对(新?)productAttributeId 的单个“批次”输入表

因此,如果选择 (1,10),这需要被阻止,因为 1-2 和 10-2 已经存在。

我的建议

存储过程应该将属性作为单个列表,例如“1,2,3”(逗号分隔,没有空格,只是整数)

然后您可以使用字符串拆分 UDF 或内联 XML 技巧(如下所示) ) 将其分解为派生表的行。

测试表

create table attrib (attributeid int, productattributeid int)
insert attrib select 1,1
insert attrib select 1,2
insert attrib select 10,2

这里我使用一个变量,但您可以将其合并为 SP 输入参数

declare @t nvarchar(max) set @t = '1,2,10'

select top(1)
  t.productattributeid,
  count(t.productattributeid) count_attrib,
  count(*) over () count_input
from (select convert(xml,'<a>' + replace(@t,',','</a><a>') + '</a>') x) x
cross apply x.x.nodes('a') n(c)
cross apply (select n.c.value('.','int')) a(attributeid)
left join attrib t on t.attributeid = a.attributeid
group by t.productattributeid
order by countrows desc

输出

productattributeid     count_attrib     count_input
2                      2                3
  1. 第一列为您提供具有最多匹配的产品属性 ID
  2. 第二列为您提供使用相同的产品属性 ID 匹配的属性数量
  3. 第三列是有多少个属性输入中存在属性

如果您比较最后 2 列并且计数

  1. 匹配 - 您可以使用 Productattributeid 附加到所有这些属性都不匹配的产品
  2. - 那么您需要执行插入操作来创建新组合

You can control your inserts via a stored procedure. My understanding is that

  1. users can select a combination of Attributes, such as
    • just 1
    • 1 and 10 together
    • 1,4,5,10 (4 attributes)

These need to enter the table as a single "batch" against a (new?) productAttributeId

So if (1,10) was chosen, this needs to be blocked because 1-2 and 10-2 already exist.

What I suggest

The stored procedure should take the attributes as a single list, e.g. '1,2,3' (comma separated, no spaces, just integers)

You can then use a string splitting UDF or an inline XML trick (as shown below) to break it into rows of a derived table.

Test table

create table attrib (attributeid int, productattributeid int)
insert attrib select 1,1
insert attrib select 1,2
insert attrib select 10,2

Here I use a variable, but you can incorporate as a SP input param

declare @t nvarchar(max) set @t = '1,2,10'

select top(1)
  t.productattributeid,
  count(t.productattributeid) count_attrib,
  count(*) over () count_input
from (select convert(xml,'<a>' + replace(@t,',','</a><a>') + '</a>') x) x
cross apply x.x.nodes('a') n(c)
cross apply (select n.c.value('.','int')) a(attributeid)
left join attrib t on t.attributeid = a.attributeid
group by t.productattributeid
order by countrows desc

Output

productattributeid     count_attrib     count_input
2                      2                3
  1. The 1st column gives you the productattributeid that has the most matches
  2. The 2nd column gives you how many attributes were matched using the same productattributeid
  3. The 3rd column is how many attributes exist in the input

If you compare the last 2 columns and the counts

  1. match - you can use the productattributeid to attach to the product which has all these attributes
  2. don't match - then you need to do an insert to create a new combination
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文