Mysql 基于多条件的SQL查询

Mysql 基于多条件的SQL查询,mysql,sql,sql-server,sql-server-2008,tsql,Mysql,Sql,Sql Server,Sql Server 2008,Tsql,基本上我有两张桌子。1表有两个重要列的列表。一般来说,第2栏中的商品不能与第1栏中的商品一起出售。它本质上是一组确定正确计费组合的规则。该表与此类似: col 1 ; col 2 ----- ----- a ---- b a ---- h a ---- d b ---- f b ---- z c ---- z c ---- d c ----

基本上我有两张桌子。1表有两个重要列的列表。一般来说,第2栏中的商品不能与第1栏中的商品一起出售。它本质上是一组确定正确计费组合的规则。该表与此类似:

col 1   ;  col 2
-----     -----
  a     ----    b
  a     ----    h
  a     ----    d
  b     ----    f
  b     ----    z
  c     ----    z
  c     ----    d
  c     ----    b
第1列中的商品不能与第2列中的商品一起出售

第二个表本质上是一个orders表。每个交易都有交易编号和行号。在每个交易行上都有已售出的商品。每笔交易通常会卖出许多商品。该表的设置与此类似:

trans # ;    trans line  ;   item
-------     -----------    -----
12345    ----       1    ----        a
12345      ----     2      ----      b
12345       ----    3    ----        a
45678      ----     1   ----         z
45678       ----    2      ----      f

我试图做的是获取所有事务数据,并将其与不适当项目组合列表上的数据进行核对。如您所见,交易12345违反了第一条规则,因为“a”与“b”一起出售。这是总体思路。

我认为这是一种解决方案 将第一个表命名为uncompt,将第二个表命名为ORDERS。 下面的查询将为您提供结果,但在实际数据库中,您可能需要进行一些更改:

select o1.item + '@' + o2.item
from orders o1 full join  orders o2 on o1.orderid = o2.orderid
where exists (select * from incompat i where o1.item + '@' + o2.item = i.col1 + '@' + i.col2)

很简单,只需使用EXISTS子句

SELECT
  COUNT(*) 
FROM 
  Trans AS Trans1 
JOIN Trans AS Trans2 ON 
  Trans1.transNb = Trans2.transNb 
WHERE CONCAT(Trans1.item, '|', Trans2.item) IN 
  (SELECT CONCAT(item1, '|', item2) FROM xCombination) 
如果计数不同于0,则顺序中的组合无效

基本上,我们用Trans1和Trans2按相同顺序对所有项目进行笛卡尔积。然后,我们用分隔符将两个项的每个组合连接在一个字符串中。如果可以在xCombination表中找到字符串,则该顺序有问题


下面是一个。

您可以通过按id加入事务来列出事务中所有可能的对。然后检查是否有任何对违反规则

select distinct a.id
from transactions a
join transactions b on a.id = b.id and a.line_num <> b.line_num
join inappropriates c on a.item = c.col1 and b.item = c.col2;

以下是选择查询:

-用于创建表和插入值的代码

Create Table InvalidCombos(item1 int, item2 int)

Create Table TransactionInfo(transactionId int, item int)

Insert Into InvalidCombos Values(1,2), (1,8), (1,4), (2,6), (2,26), (3,26), (3,4), (3,2)

Insert Into TransactionInfo Values(12345,1), (12345,2), (45678,26), (45678,6)
-以下是select语句及其结果:

Select ic.item1, ic.item2, transinfo.transactionId From invalidcombos ic 
  INNER JOIN ( 
    Select ti1.transactionId, ti1.item as item1, ti2.item as item2 
      From TransactionInfo ti1 
      LEFT JOIN TransactionInfo ti2 ON ti1.transactionid = ti2.transactionid 
      and ti1.item <> ti2.item
    )
    transinfo ON (transinfo.item1 = ic.item1 AND transinfo.item2 = ic.item2)

在表2中使用一个自完全联接,以获得每个顺序中的所有组合,怎么样。然后简单地将其内部连接到表1

select * into #t1 from
(
    select 'a' as col1, 'b' as col2
    union
    select 'a' as col1, 'h' as col2
    union
    select 'a' as col1, 'd' as col2
) q


select * into #t2 from
(
select 1 as trans, 1 as line, 'a' as item
union
select 1 as trans, 2 as line, 'b' as item
union
select 1 as trans, 3 as line, 'a' as item
union
select 2 as trans, 1 as line, 'z' as item
union
select 2 as trans, 2 as line, 'f' as item
) q

select o.* from #t1 as v
inner join
(
    select distinct a.trans, a.item as item1, b.item as item2
    from #t2 as a
    full join #t2 as b on a.trans = b.trans and a.line <> b.line
) as o on v.col1 = o.item1 and v.col2 = o.item2

在第一个表中,它会有一行表示a不能与b一起出售,另一行表示b不能与a一起出售吗?这可能与我最终所做的有70%相似。这是一个很好的开始。不过有几个问题-首先是这计算了2个错误,实际上只有1个。我想这意味着它会重复计算每件事,可以用2除以2来修正,但还是有点混乱。。第二,也是更重要的一点,如果有超过2个交易编号,这将不起作用。还有很多。有时是90+。我喜欢连接方法,但我可能必须使用FOR XML将行连接在一起,而不必执行连接或数据透视。由于组合ab是两倍,因此顺序12345中有两个错误。还有,为什么您说它不适用于多个事务号?从select trans1.transNb中选择com.id、a.transNb、a.item、a.t2,trans1.item、trans2.item as t2 FROM Trans as trans1在trans1.transNb=trans2.transNb上加入Trans as trans2在a.item=com.item1和a.t2=com.item2上的左连接xCombination com,其中com.item1不为空
select * into #t1 from
(
    select 'a' as col1, 'b' as col2
    union
    select 'a' as col1, 'h' as col2
    union
    select 'a' as col1, 'd' as col2
) q


select * into #t2 from
(
select 1 as trans, 1 as line, 'a' as item
union
select 1 as trans, 2 as line, 'b' as item
union
select 1 as trans, 3 as line, 'a' as item
union
select 2 as trans, 1 as line, 'z' as item
union
select 2 as trans, 2 as line, 'f' as item
) q

select o.* from #t1 as v
inner join
(
    select distinct a.trans, a.item as item1, b.item as item2
    from #t2 as a
    full join #t2 as b on a.trans = b.trans and a.line <> b.line
) as o on v.col1 = o.item1 and v.col2 = o.item2