【问题标题】:SQL | Select (...) where 2 columns combined equal (xy)SQL |选择 (...) 其中 2 列组合等于 (xy)
【发布时间】:2016-04-20 13:41:01
【问题描述】:

我不知道如何有效地解决以下问题。

给定

1。 电话号码作为单个字符串,例如:1111223344

2。 具有此编号split in 2 different Columns 的数据库 (ColA 中号码的第一部分,ColB 中的号码的第二部分) |数据库很大(高达 100 GB)

假设在 ColA 中是 '11112' 在 ColB 中是 '23344' - 结合这 2 列是我们正在寻找的字符串。我们不知道哪一列有多少个字符。

需要:选择语句,即combines ColA + ColB and compares it to the given String。如果相等:选择行。

所选行/行将被选择并与 .Net 应用程序一起使用。

【问题讨论】:

  • 你试过基本的字符串连接吗?其中 ColA + ColB = @StringGiven
  • 电话号码总是分成5和5吗?
  • 我会引用自己的话:I have no Idea how i could - 我通常会尽力自己解决问题。但正如我在问题中所说的那样:我什至不知道这个如何工作。 Ofc 我有想法如何在我的 .net 应用程序中解决这个问题,但这将非常无效。
  • 我应该补充一点,我不太了解 SQL。如邮报所述;我们不知道哪一列中有多少个字符 - 也可以是 1 / 9 或 2/20。 @ScottChamberlain 不,我什至不知道那是什么:-)
  • 你说你不知道,但你几乎在你的问题中发布了语法。试试我在第一条评论中发布的 where 子句。

标签: sql .net oracle


【解决方案1】:

这应该可以帮助您入门。您将需要根据实际需求进行调整。

如果保证两个值都是字符串:

SELECT *
FROM MyTable m
WHERE m.ColA + m.ColB = '1111223344'

如果这两个值不能保证是字符串:

SELECT *
FROM MyTable m
WHERE CONCAT(m.ColA, m.ColB) = '1111223344'

【讨论】:

  • 呃。为什么 NOLOCK 提示?那太糟糕了。如果你打算使用它,你至少应该包含 WITH 关键字。不推荐省略它。
  • 老实说,这不会很好,因为我认为它不会使用任何索引,为什么是 NOLOCK?
  • @DunningKrugerEffect 您应该阅读并了解 NOLOCK 提示的实际作用。 blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
  • 我有。由于我组织的要求,这已成为习惯。我已经编辑了我的答案以删除 nolocks。
  • @Luke 阅读了这篇文章。 blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere 它可以使您的查询稍微快一些,但这是有代价的。成本就是准确性。许多人认为这只是脏读,但它远不止于此。它可以并且将返回丢失和/或重复的行。如果查询的准确性很重要,请避免它。 NOLOCK 有它的位置,但不是无处不在。
【解决方案2】:

我能想到的一种方法是,使用 Hashbytes 作为计算列。您也可以索引此列以获得良好的性能..

CREATE TABLE #TESTMAIN
(
NMBR VARCHAR(10)
)
INSERT INTO #TESTMAIN
SELECT '123456'
UNION ALL
SELECT '3456'

create table #backup
(
nmbr1 varchar(10),
nmbr2 varchar(10)
)

insert into #backup
select '123','456'
union all
select '34','56'

Alter table #testmain
add mainnmbr as hashbytes('SHA1',nmbr)

select * from #testmain

Alter table #backup
add bckpnmbr as hashbytes('SHA1',concat(nmbr1,nmbr2))

select * from #testmain
select * from #backup

现在您可以对下面的数据进行简单的比较..

【讨论】:

  • 对我来说不是一个选项,因为我只有对数据库的选择权限。但是非常感谢您编写该查询!
【解决方案3】:

如果您的要求只是找到串联为 xy 的行集,那么您可以试试这个:

DECLARE @x VARCHAR(50), @y VARCHAR(50)

SELECT ColA, ColB
FROM Source WITH NOLOCK --If you like, depending on your environment
WHERE ColA = @x AND ColB = @y

NOLOCK 业务取决于可能与您的查询同时写入数据库的其他人。如果您自己拥有数据库,或者它严格用于读取操作,那就太好了。如果您有可能在白天或晚上的任何时间发生的关键任务写入,那就不是这样了。当然,您需要适当地调整@x 和@y 的大小。如果你有一个 7 位数字的区号,没有装饰 @x 可能是 VARCHAR(3) 而@y 可能是 VARCHAR(7)

【讨论】:

  • NO 如果您需要准确的结果,NOLOCK 提示仍然很危险。这不是一个神奇的快速按钮。它有一些非常严重的影响,但经常被掩盖。
  • 这意味着如果你不在一个孤立的环境中,读取未提交的隔离级别是危险的。但它仍然是最快的。这是我们都考虑的权衡。性能与安全性。安全并不是所有情况下最重要的问题。
  • 我要补充一点,它不是神奇的按钮,但绝对是更快的按钮。注意到严重的影响。
  • 它更快,但通常不是很多。对于汇总报告之类的事情,这很好。我不明白你关于安全的观点。 NOLOCK 根本与安全无关。它与准确性有关。如果一个结果集在大多数情况下都相当接近(如果可以接受的话),那么轻微的性能提升可能是可以的。在大多数 OLTP 系统中,大多数情况下这是不可接受的。
  • 确实,准确性比安全性更准确。在我的业务中,它们是同义词。
【解决方案4】:

如果您的读取次数多于写入次数,您可以通过使用基于功能的索引 (more info) 和 DunningKrugerEffect 建议的查询来提高性能。如果不创建该索引,您将进行全表扫描,这对大表不利。

SELECT *
FROM MyTable m 
WHERE CONCAT(m.ColA, m.ColB) = '1111223344'

【讨论】:

  • 我已经让它工作了,但我不得不移除 NOLOCK。是因为它使用 Oracle SQL,还是因为没有足够的数据库权限?你能解释一下,NOLOCK 到底是做什么的?
  • NOLOCK 在这里更好地描述:brentozar.com/archive/2011/11/…
  • 卢克你能分享一些基准,有和没有基于函数的索引吗?用于读取和写入以及您的表有多大。
猜你喜欢
  • 2022-11-20
  • 2023-03-02
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2016-07-12
  • 2018-10-18
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多