0

How can I write a query that prints in response to letters by giving row ID and size number?

enter image description here

Example:

ID = 4000

NAME = 38/39/40/41/42/43/44


My Input :

ID = 4000

NAME = 40


Result = A/B/C/D/E/F/G 40 = C

masoud Goodarzi
  • 72
  • 1
  • 1
  • 6
  • 2
    I really don't follow what you are asking here; you need to elaborate. – Thom A Apr 12 '22 at 10:44
  • 2
    Also, why are you storing delimited data in your database? I strongly recommend you fix your design; this would likely be far easier too if you did. – Thom A Apr 12 '22 at 10:45
  • 4
    Those appear to be sizes, not "names". That table looks like a classic (mis)application of a generic "string lookup" table that could do with some pre-processing first. That could be done in T-SQL if `STRING_SPLIT` is available, if not, it's painful. – Jeroen Mostert Apr 12 '22 at 10:49
  • You have to give clarifications, it looks like each of **38/39/40** is a foreign key, if I am not wrong, when someone asks for **ID = 4000 and selects 40, it needs to get some other results C**, so please give some explanation, image or diagram – AwatITWork Apr 12 '22 at 10:54
  • @Larnu if i write in my query '40' then result 'C' – masoud Goodarzi Apr 12 '22 at 10:57
  • Where does C come from? – Thom A Apr 12 '22 at 10:58
  • @Larnu ----It can be anything. For example, we have two sizes == 40/44 .. If I write 44 in the query condition, it will show me the letter B. – masoud Goodarzi Apr 12 '22 at 11:02
  • 1
    So the C can be anything? Why not Q then? Why not Apple? If you don't know where C comes from (and B in the second example), then we have *no* idea. – Thom A Apr 12 '22 at 11:07
  • @Larnu Dear friend, I think I explained exactly what my problem is and what I want. These letters are to be specified elsewhere in the program My problem right now is the question I asked. – masoud Goodarzi Apr 12 '22 at 12:17
  • *"These letters are to be specified elsewhere in the program"* where? This **is** the question, we don't know how to produce the results you want – Charlieface Apr 12 '22 at 12:46
  • 2
    So, the short of it is, split the data (presumably with `STRING_SPLIT`) and then `JOIN` to the data you haven't showed us, and filter to the value you want. There are plenty of questions/articles/tutorials/documentation on how to split a string in T-SQL, so what about those didn't you understand and why didn't they work? If you haven't looked at any, I suggest you do. I *assume* you don't need examples of how to do a `JOIN` or `WHERE`, however, if you do then you are lacking fundament knowledge on SQL; you need to learn those first. – Thom A Apr 12 '22 at 12:59
  • Does this answer your question? [Turning a Comma Separated string into individual rows](https://stackoverflow.com/questions/5493510/turning-a-comma-separated-string-into-individual-rows) – Thom A Apr 12 '22 at 13:01

1 Answers1

1

Please try the following solution.

SQL

-- DDL and sample data population, start
DECLARE @tbl AS TABLE (ID INT PRIMARY KEY, tokens VARCHAR(MAX));
INSERT INTO @tbl (ID, tokens) VALUES
(2000, '44/46/48/50/52/54'),
(4000, '38/39/40/41/42/43/44');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = '/'
    , @alphabet VARCHAR(50) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    , @ID INT = 4000
    , @token VARCHAR(20) = '40';

SELECT *
    , Result = IIF(pos > 0, SUBSTRING(@alphabet,pos,1),NULL)
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r>' + 
    REPLACE(tokens, @separator, '</r><r>') + 
    '</r></root>' AS XML)
    .query('
        for $x in /root/r
        let $pos := count(/root/r[. << $x[1]]) + 1
        return if ($x/text()=sql:variable("@token")) then $pos
        else ()
    ').value('.', 'INT')) AS t1(pos)
WHERE ID = @ID;

Output

+------+----------------------+-----+--------+
|  ID  |        tokens        | pos | Result |
+------+----------------------+-----+--------+
| 4000 | 38/39/40/41/42/43/44 |   3 | C      |
+------+----------------------+-----+--------+
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21
  • 1
    The same, with less code and better performance can be done with `STRING_SPLIT`. STRING_SPLIT is available in all SQL Server versions in mainstream support. A far better solution though would be to just fix the bad table design. While STRING_SPLIT is far faster than XML even if indexed, nothing beats a separate `Sizes` table with proper columns and indexes – Panagiotis Kanavos Apr 12 '22 at 13:19
  • @PanagiotisKanavos, Unfortunately, we don't know the OP's SQL Server version. So I was targeting a lowest denominator. Also, for a single row the performance difference will be close to zero. And the `STRING_SPLIT()` function doesn't guarantee a sequential order. – Yitzhak Khabinsky Apr 12 '22 at 13:22
  • 2
    The OP didn't ask for the position. There's no position in relational databases anyway, unless some kind of order is imposed. As for the version, `STRING_SPLIT` was introduced in a version that's already out of support. We *can* assume this is a supported version unless explicitly specified. Otherwise one could question whether XML support is available (a bit extreme but still) – Panagiotis Kanavos Apr 12 '22 at 13:36