SQL WHERE匹配任何列中的任何值

时间:2015-07-10 18:17:30

标签: sql sql-server sql-server-2008-r2

我需要一个包含4列订单号的表A:Order1,Order2,Order3,Order4(我知道,这很糟糕,但这是给定的)。

我必须在表B中找到记录,其中匹配是表A中任何顺序列中的任何值都可以在B列中的任何顺序:

A.Order1 = B.Order1 OR
A.Order1 = B.Order2 OR
A.Order1 = B.Order3 OR
A.Order1 = B.Order4 OR
A.Order2 = B.Order1 etc

有没有更好的方法来写这个? 我们害怕他们告诉我他们想要使用5或6列的那一刻。

编辑原始问题

  • 这适用于SQL Server 2008 R2
  • 表B还有4个订单号为
  • 的订单列
  • 我正在寻找表A中任何订单列中的任何订单号,以匹配表B中任何订单列中的任何订单号。
  • 没有预料到的最有可能的发现

3 个答案:

答案 0 :(得分:2)

您可以使用交叉应用取消一个表中的列,然后检查交叉应用中的值是否位于另一个表的任何列中。

如果您添加新列,它不会自动工作,但您只需要在一两个位置添加它们。

SQL Fiddle

MS SQL Server 2014架构设置

select *
from A
where exists (
             select *
             from B
               cross apply (values(B.Order1),(B.Order2),(B.Order3),(B.Order4)) as X(O)
             where X.O in (A.Order1, A.Order2, A.Order3, A.Order4)
             )       

查询1

| Order1 | Order2 | Order3 | Order4 |
|--------|--------|--------|--------|
|      1 |      1 |     40 |     10 |

<强> Results

<html>
<head>
    <title>navbarTest</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <style>
        body { padding-top: 70px; }
    </style>
</head>
<body>
    <div class="container">
    <div class="jumbotron" style="top:15em; width=100%; margin-bottom:0;">
        <div class="row">
            <div class="col-md-12">
                <nav class="navbar navbar-inverse role="banner" style="margin-bottom:0;"">
                    <div class="container-fluid">
                        <div class="navbar-header">
                        <a href="navbarTest.html" class="navbar-brand">Navbar Example</a>
                        </div>
                    <div class="navbar-text navbar-right">
                    <a href="navbarTest.html" class="navbar-link">
                        holaaa
                    </a>
                    </div>
                    </div>
                </nav>
            </div>
        </div>

    </div>
    </div>
<script type="text/javascript" href="C:\Users\alan.martinez.blanco\Downloads\jquery-2.1.4.min.js"></script>
<script type="text/javascript" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

答案 1 :(得分:1)

使用您拥有的模型设计实现此目的的唯一方法是(像@GordonLinoff建议的那样):

where b.order1 in (a.order1, a.order2, a.order3, a.order4) or
      b.order2 in (a.order1, a.order2, a.order3, a.order4) or
      b.order3 in (a.order1, a.order2, a.order3, a.order4) or
      b.order4 in (a.order1, a.order2, a.order3, a.order4) 

您可能遇到的一个有趣问题是如何更改数据模型以使其更好地工作? ......这是如何:

首先你有两个表A和B.我将假设A和B都有一个唯一的索引ID。

然后,您可以使用以下列创建支持表AOrder

AID 
ORDNUM
VALUE

如果您为BOrder创建一个类似的表,那么要查明给定的订单是否相同,只需加入Value并获得AID,BID和两个订单号。

使用此设计,您无需关心有多少订单号。

您可以像这样动态地将当前数据转换为此设计,并获得您想要的结果:

 SELECT aord.ID as aID, bord.ID as bID, a.num as a_ordernum, b.num as b.ordernum, v 
 FROM (
   SELECT a.ID, 1 AS num, a.order1 as V FROM a
     UNION ALL
   SELECT a.ID, 2 AS num, a.order2 as V FROM a
     UNION ALL
   SELECT a.ID, 3 AS num, a.order3 as V FROM a
     UNION ALL
   SELECT a.ID, 4 AS num, a.order4 as V FROM a
 ) aord
 JOIN (
   SELECT b.ID, 1 AS num, b.order1 as V FROM b
     UNION ALL
   SELECT b.ID, 2 AS num, b.order2 as V FROM b
     UNION ALL
   SELECT b.ID, 3 AS num, b.order3 as V FROM b
     UNION ALL
   SELECT b.ID, 4 AS num, b.order4 as V FROM b
 ) bord on aord.v = bord.v

答案 2 :(得分:0)

你可以将它们标准化吗?我假设您有一个SetID字段,将A和B中的4个(或更多)订单分组,因此您可以拥有一个表/视图:

    select ID, srctbl, seq, order
    from (
    select AID as ID, 'A' as srctbl, 1 as seq, order1 as order from tblA union all
    select AID, 'A' as srctbl, 2, order2 from tblA union all
    select AID, 'A' as srctbl, 3, order3 from tblA union all
    select AID, 'A' as srctbl, 4, order4 from tblA union all
    select BID, 'B' as srctbl, 1, order1 from tblB union all
    select BID, 'B' as srctbl, 2, order2 from tblB union all
    select BID, 'B' as srctbl, 3, order3 from tblB union all
    select BID, 'B' as srctbl, 4, order4 from tblB )

然后你可以说

select ID, srctbl, seq, order 
from (select ID, srctbl, seq, order from tbl where srctbl = 'a') ta inner join
((select ID, srctbl, seq, order from tbl where srctbl = 'b') tb on
ta.order = tb.order

或者,作为CTE:

WITH orders (ID, srctbl, SEQ, orderVal)
AS (
   SELECT ID, srctbl, SEQ, orderVal
    FROM (
    SELECT AID AS ID, 'A' AS srctbl, 1 AS SEQ, order1 AS orderVal FROM tblA UNION ALL
    SELECT AID, 'A' AS srctbl, 2, order2 FROM tblA UNION ALL
    SELECT AID, 'A' AS srctbl, 3, order3 FROM tblA UNION ALL
    SELECT AID, 'A' AS srctbl, 4, order4 FROM tblA UNION ALL
    SELECT BID, 'B' AS srctbl, 1, order1 FROM tblB UNION ALL
    SELECT BID, 'B' AS srctbl, 2, order2 FROM tblB UNION ALL
    SELECT BID, 'B' AS srctbl, 3, order3 FROM tblB UNION ALL
    SELECT BID, 'B' AS srctbl, 4, order4 FROM tblB )
)

SELECT ta.ID AS a_id, tb.ID AS b_ID, ta.SEQ AS a_seq, tb.SEQ AS b_seq, ta.orderVal 
FROM 
 (SELECT ID, SEQ, orderVal FROM orders WHERE srctbl = 'a') ta INNER JOIN
 (SELECT ID, SEQ, orderVal FROM orders WHERE srctbl = 'b') tb ON
ta.orderVal = tb.orderVal