有没有办法寻找改变位置的无序值?

Posted

技术标签:

【中文标题】有没有办法寻找改变位置的无序值?【英文标题】:Is there a way to look for unordered values ​that change position? 【发布时间】:2021-10-09 01:36:47 【问题描述】:

有一个包含 50 列的表,它们都包含从 1 到 99 的数字。如果我想搜索,例如8,36,52不管在哪里,只要在同一个元组里,我会做吗?我被卡住了,因为如果我指定列,我会限制搜索。拜托,欢迎任何帮助!

【问题讨论】:

根据问题指南,请展示您尝试过的内容并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。另请提供minimal reproducible example,包括样本数据、所需结果和您的尝试。 where (c1=8 or c2=8 or c3=8...) and (c1=36 or c2=36 or c3=36...) and (c1=52 or c2=52 or c3=52...)? 基本上,如果您有 50 列数字如此难以区分,以至于集体搜索它们以查找匹配的数字是有意义的,而不管它们分配的列,那么您就有了一个糟糕的(非关系)数据设计。您有时可以证明跨列搜索文本子字符串是合理的,但很少会搜索数字:它们应该被设计为一开始就在一个列中。 【参考方案1】:

这将动态地 UNPIVOT 行,而不必使用动态 SQL

示例或dbFiddle

Declare @Search varchar(50)='8,36,52';

with cte as (
 Select Distinct Value From string_split(@Search,',')
) 
Select A.* 
 From YourTable A
 Cross Apply (
                Select Hits =Count(Distinct B1.Value)
                 From OpenJson((Select A.* For JSON Path,Without_Array_Wrapper )) B1
                 Join cte B2 on B1.Value=B2.Value
             ) B
 Where Hits = ( select count(*) from cte )

【讨论】:

【参考方案2】:

这是另一种基于 XML/XQuery 的方法。

它使用 XQuery 的 量化表达式

Quantified Expressions (XQuery)

给定两个序列,如果第一个序列中的每个项目在第二个序列中都有匹配,则返回值为 True。正是我们需要的。

CTE 中的 XML 对于每一行如下所示:

<root>
  <source>
    <r>8</r>
    <r>36</r>
    <r>52</r>
  </source>
  <target>
    <ID>1</ID>
    <Col1>0</Col1>
    <Col2>15</Col2>
    <Col3>45</Col3>
    <Col4>7</Col4>
    <Col5>88</Col5>
    <Col6>22</Col6>
  </target>
</root>

SQL

-- DDL and data population, start
DECLARE @tbl TABLE
(
    ID INT IDENTITY PRIMARY KEY,
    [Col1] INT,
    [Col2] INT,
    [Col3] INT,
    [Col4] INT,
    [Col5] INT,
    [Col6] INT
);
INSERT INTO @tbl
VALUES
(0, 15, 45, 7, 88, 22),
(1, 36, 8, 7, 14, 52),
(32, 36, 36, 1, 1, 1); -- Duplicate Values
-- DDL and data population, end

DECLARE @Search VARCHAR(50) = '8,36,52'
    , @separator CHAR(1) = ',';

;WITH rs AS
(
    SELECT * 
    , TRY_CAST('<root>' + 
       '<source><r><![CDATA[' + REPLACE(@Search, @separator, ']]></r><r><![CDATA[') + 
          ']]></r></source>' + 
       (SELECT * FROM @tbl AS c 
       WHERE p.ID = c.ID
       FOR XML PATH(''), ROOT('target')) + 
       '</root>' AS XML)
          .query('every $x in /root/source/r/text()
                satisfies ($x = (/root/target/*[local-name()!="ID"]/text()))')
          .value('text()[1]', 'bit') result
    FROM @tbl AS p
)
SELECT * FROM rs
WHERE rs.result = 1;

【讨论】:

以上是关于有没有办法寻找改变位置的无序值?的主要内容,如果未能解决你的问题,请参考以下文章

set集合知识

有没有办法让 UIScrollView 在任意位置停止和反弹

如何使用 Cocoa 改变鼠标位置差异?

如何用 CSS 改变滚动条的位置?

举个栗子!Tableau 技巧(210):改变标签和列名称的位置

如何在图像上实现拖放,改变其位置