简体   繁体   English

SQL查询从表中选择并在另一列上分组

[英]SQL query select from table and group on other column

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. 我有一个带有两个ID列的链接/联接表。 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: 这是我的意思的图片:

在此处输入图片说明

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. 因此,如果用户现在尝试保存ID为1的属性,它将停止它们,但是,如果他们尝试ID为1、10的情况,只要1和10具有相同的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. 这应该很简单,所以我想我缺少了一些东西。

If I understand the question properly, you want to prevent the combination of AttributeId and ProductAttributeId from being reused. 如果我对问题的理解正确,则希望防止AttributeIdProductAttributeId的组合被重用。 If that's the case, simply make them a combined primary key, which is by nature UNIQUE . 如果是这种情况,只需将它们组合为一个主键,这自然就是UNIQUE

If that's not feasible, create a stored procedure that runs a query against the join for instances of the AttributeId . 如果这不可行,请创建一个存储过程,以对AttributeId实例的AttributeId运行查询。 If the query returns 0 instances, insert the row. 如果查询返回0个实例,请插入行。

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

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
    • 1 and 10 together 1和10在一起
    • 1,4,5,10 (4 attributes) 1,4,5,10(4个属性)

These need to enter the table as a single "batch" against a (new?) productAttributeId 这些需要针对(新?)productAttributeId作为单个“批”输入表

So if (1,10) was chosen, this needs to be blocked because 1-2 and 10-2 already exist. 因此,如果选择了(1,10),则需要将其阻止,因为1-2和10-2已经存在。

What I suggest 我的建议

The stored procedure should take the attributes as a single list, eg '1,2,3' (comma separated, no spaces, just integers) 存储过程应将属性作为单个列表使用,例如'1,2,3'(逗号分隔,无空格,仅整数)

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. 然后,您可以使用字符串拆分UDF或内联XML技巧(如下所示)将其拆分为派生表的行。

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 我在这里使用一个变量,但是您可以将其作为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

Output 输出量

productattributeid     count_attrib     count_input
2                      2                3
  1. The 1st column gives you the productattributeid that has the most matches 第一列为您提供匹配次数最多的productattributeid
  2. The 2nd column gives you how many attributes were matched using the same productattributeid 第二列为您提供了使用相同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 匹配-您可以使用productattributeid附加到具有所有这些属性的产品
  2. don't match - then you need to do an insert to create a new combination 不匹配-那么您需要插入以创建新的组合

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM