SQL – 选择所有在位置10和位置20的字符之间差值等于1的条目?

huangapple go评论72阅读模式
英文:

SQL - Select all Entries where the difference between Characters at Position 10 and Position 20 Equals 1?

问题

You can construct a query to obtain BATCH_IDs where the difference between the 10th and 20th characters is greater than 1 in the Oracle Database. Here's the query:

SELECT BATCH_ID
FROM EM_EQUIPMENT_LG
WHERE TO_NUMBER(SUBSTR(BATCH_ID, 10, 1)) - TO_NUMBER(SUBSTR(BATCH_ID, 20, 1)) > 1;

This query will return BATCH_IDs where the difference between the 10th and 20th characters is greater than 1, as requested.

英文:

I work in a factory that manufactures electrical sensors.

We manufacture the Sensors in Batches (there's 10,000 Sensors in a Batch).
The Batches are referred to by Numbers like 1000585855; with the last 6 Digits being unique to each Batch.

The first stage of manufacturing the Sensor however (on a machine called Dispense), involves two Batches being processed together.

Generally, the Batches only differ by the last digit being +1 larger.
So for Batch 1000585855, the 'sister lot' will be 1000585856.
(When we reference these Lots being processed on Dispense in the Database, they are quoted as 1000585855_000585856.)

Occasionally however, the sister lot may be +2 or +3 larger (really it can be + any natural number).
So for example, I have seen 1000456872_0000456874.

The information relating to the batches is stored in an Oracle Database Table.
The Table is called the EM_EQUIPMENT_LG Table and is structured like so:

EQUIPMENT_ID BATCH_ID
Dispense 1000731655_000731656
Dispense 1000746832_000746833
Dispense 1000731637_000731639
Dispense 1000575235_000575236

Is it possible to construct a Query, whereby I obtain the BATCH_IDs, only where the difference between the 10th and 20th Characters (Bolded) is greater than 1?

So, if I was to utilise such a Query in the above example table, the only BATCH_ID returned should be 1000731637_9. (As 9 minus 7 = 2)

答案1

得分: 1

-- 以下是已翻译的内容:

WITH
    tbl (EQUIPMENT_ID, BATCH_ID) AS
    (
        Select 'Dispense', '1000731655_000731656' From Dual Union All
        Select 'Dispense', '1000746832_000746833' From Dual Union All
        Select 'Dispense', '1000731637_000731639' From Dual Union All
        Select 'Dispense', '1000575235_000575236' From Dual
    )

SELECT  EQUIPMENT_ID, BATCH_ID
FROM    tbl
WHERE   To_Number(SubStr(BATCH_ID, 20, 1)) - To_Number(SubStr(BATCH_ID, 10, 1)) > 1
-- Maybe it would be better  to take two chars like  9th and 10th with 19th and 20th as there could be some problems with numbers ending with 0. Used To_number() because I dont like to be dependant on implicite conversions.
-- 也许更好的方法是选择第9和10个字符以及第19和20个字符,因为以0结尾的数字可能会有问题。使用To_number()是因为我不喜欢依赖隐式转换。

WHERE To_Number(SubStr(BATCH_ID, 19, 2)) - To_Number(SubStr(BATCH_ID, 9, 2)) > 1
英文:
WITH			--	S a m p l e   D a t a :
	tbl (EQUIPMENT_ID, BATCH_ID) AS
		(	
			Select 'Dispense', '1000731655_000731656' From Dual Union All
			Select 'Dispense', '1000746832_000746833' From Dual Union All
			Select 'Dispense', '1000731637_000731639' From Dual Union All
			Select 'Dispense', '1000575235_000575236' From Dual
		)
--	M a i n   S Q L :
SELECT  EQUIPMENT_ID, BATCH_ID
FROM 	tbl
WHERE	To_Number(SubStr(BATCH_ID, 20, 1)) - To_Number(SubStr(BATCH_ID, 10, 1)) > 1
--	
--	R e s u l t :
--  EQUIPMENT_ID BATCH_ID            
--  ------------ --------------------
--  Dispense     1000731637_000731639

Maybe it would be better to take two chars like 9th and 10th with 19th and 20th as there could be some problems with numbers ending with 0. Used To_number() because I dont like to be dependant on implicite conversions.

WHERE To_Number(SubStr(BATCH_ID, 19, 2)) - To_Number(SubStr(BATCH_ID, 9, 2)) > 1

答案2

得分: 0

你可以使用 SUBSTR 来查找这些位置上的字符,然后进行减法运算(会隐式地将它们转换为数字):

SELECT *
FROM   table_name
WHERE  ABS(SUBSTR(batch_id, 20, 1) - SUBSTR(batch_id, 10, 1)) > 1;

对于示例数据:

CREATE TABLE table_name (EQUIPMENT_ID, BATCH_ID) AS
SELECT 'Dispense', '1000731655_000731656' FROM DUAL UNION ALL
SELECT 'Dispense', '1000746832_000746833' FROM DUAL UNION ALL
SELECT 'Dispense', '1000731637_000731639' FROM DUAL UNION ALL
SELECT 'Dispense', '1000575235_000575236' FROM DUAL UNION ALL
SELECT 'Dispense', '1000575239_000575240' FROM DUAL;

输出:

EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639
Dispense 1000575239_000575240

或者,如果你想使用所有 6 位数字,那么可以这样:

SELECT *
FROM   table_name
WHERE  ABS(SUBSTR(batch_id, 15, 6) - SUBSTR(batch_id, 5, 6)) > 1;

这将输出:

EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639

fiddle

英文:

You can use SUBSTR to find the characters at those positions and then subtract (implicitly converting them to numbers):

SELECT *
FROM   table_name
WHERE  ABS(SUBSTR(batch_id, 20, 1) - SUBSTR(batch_id, 10, 1)) > 1;

Which, for the sample data:

CREATE TABLE table_name (EQUIPMENT_ID, BATCH_ID) AS
SELECT 'Dispense', '1000731655_000731656' FROM DUAL UNION ALL
SELECT 'Dispense', '1000746832_000746833' FROM DUAL UNION ALL
SELECT 'Dispense', '1000731637_000731639' FROM DUAL UNION ALL
SELECT 'Dispense', '1000575235_000575236' FROM DUAL UNION ALL
SELECT 'Dispense', '1000575239_000575240' FROM DUAL;

Outputs:

EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639
Dispense 1000575239_000575240

Or, if you want to use all 6 digits then:

SELECT *
FROM   table_name
WHERE  ABS(SUBSTR(batch_id, 15, 6) - SUBSTR(batch_id, 5, 6)) > 1;

Which outputs:

EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639

fiddle

答案3

得分: 0

在数字长度不固定的情况下,您可以尝试以下操作:

CREATE TABLE batch
    ("EQUIPMENT_ID" varchar2(8), "BATCH_ID" varchar2(20))
;
INSERT ALL 
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000731655_000731656')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000746832_000746833')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000731637_000731639')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000575235_000575236')
SELECT * FROM dual
4 rows affected
SELECT * FROM batch t
  WHERE To_Number(SUBSTR(SUBSTR(t."BATCH_ID", INSTR(t."BATCH_ID", '_')+1),-1)) 
   - To_Number(SUBSTR(SUBSTR(t."BATCH_ID", 1, INSTR(t."BATCH_ID", '_')-1),-1)) 
         > 1 
EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639

fiddle

英文:

In xase that the numabers are not fixed length you can try

CREATE TABLE batch
    ("EQUIPMENT_ID" varchar2(8), "BATCH_ID" varchar2(20))
;

INSERT ALL 
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000731655_000731656')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000746832_000746833')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000731637_000731639')
    INTO batch ("EQUIPMENT_ID", "BATCH_ID")
         VALUES ('Dispense', '1000575235_000575236')
SELECT * FROM dual
4 rows affected
SELECT * FROM batch t
  WHERE To_Number(SUBSTR(SUBSTR(t."BATCH_ID", INSTR(t."BATCH_ID", '_')+1),-1)) 
   - To_Number(SUBSTR(SUBSTR(t."BATCH_ID", 1, INSTR(t."BATCH_ID", '_')-1),-1)) 
         > 1 
  
EQUIPMENT_ID BATCH_ID
Dispense 1000731637_000731639

fiddle

huangapple
  • 本文由 发表于 2023年6月12日 22:04:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76457443.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定