Many to many comparison in SQL Server - sql

In SQL Server the column contains some center codes in comma separated formats like
0000700118,0000700120,0000700123,0000700163.
and the values compared by same value but the center code separation order is different LIKE 0000700123,0000700118,0000700120,0000700163.
How to compare the many to many values in SQL Server. Help me anyone to resolve the issue.

To find rows which have the same values in CostElementName (with/without the same ordering):
declare #t table
(
id int identity,
CostElementGroup varchar(10),
CostElementName varchar(max)
);
insert into #t
(
CostElementGroup, CostElementName
)
values ('A', '1, 2, 3, 4, 5'), ('A', '5, 4, 3, 2, 1'),
('A', '3, 4, 5'), ('A', '3, 5, 4'),
('A', '1, 2, 3'), ('A', '1, 2');
select *
from #t as a
join #t as b on a.CostElementGroup = b.CostElementGroup and a.id <> b.id
where
--same number of elements in the comma delimited string...
len(a.CostElementName) - len(replace(a.CostElementName, ',', '')) = len(b.CostElementName) - len(replace(b.CostElementName, ',', ''))
and not exists --...without any diff
(
select ltrim(x.value)
from string_split(a.CostElementName, ',') as x
except
select ltrim(y.value)
from string_split(b.CostElementName, ',') as y
);

You should not have all the values in a single string. Try and parse the data before introducing it in the table so that you can add each element on a new line in the table as a varchar. Afterwards, it's easier to compare the entire column with a value.

Related

How to concat all values associated with a key?

I have the following schema:
CREATE TABLE table1
(
user,
phoneType, --from ['A','B','C','D', 'E'], user can have any number of any type
uniquePhoneID, --unique string identifying the phone
day_id --date; record does not necessarily exist for every seen user + phoneType every day, represented as number in example
);
INSERT INTO table1
VALUES (1, 'A', xyz, 1),
(1, 'A', abc, 1),
(1, 'B', def, 2),
(1, 'A', xyz, 2),
(1, 'C', hij, 4),
(1, 'A' xyz, 5),
(2, 'C', w, 9),
(2, 'D', z, 10),
(2, 'A', p, 10),
(2, 'E', c, 11),
(3, 'A', r, 19),
(3, 'B', q, 19),
(3, 'B', q, 20),
(3, 'B', f, 20),
(3, 'B', y, 21);
A single user, uniquePhoneID, day_id will only show up at most once, but not necessarily at all on any given day.
I am looking to concatenate each user in the table with their 4 phoneTypes in alphabetical order, so the result is as follows:
1 | AABC
2 | ACDE
3 | ABBB
I have tried a few different ways of doing this but I am unsure how to get the answer I am looking for.
I think user is a reserved word, so you will have to resolve that. Otherwise, I think something like this will work for you:
select user, string_agg (phonetype, '' order by phonetype)
from table1
group by user
-- EDIT 4/21/2022 --
Aah, okay. I did not glean that from the original question.
What if you used the distinct on the original table before the aggregation?
select userid, string_agg (phonetype, '' order by phonetype)
from (select distinct userid, phonetype, uniquephoneid from table1) x
group by userid
I got these results from this version:
1 AABC
2 ACDE
3 ABBB
If that logic still doesn't work, can you alter the sample data to find an example where it fails?

Query response in JSON format without column name

My table schema is something like this,
DECLARE #mytable AS TABLE(ID INT, EmpName VARCHAR(10), Age INT);
INSERT INTO #mytable
VALUES
(1, 'a', 1),
(2, 'b', 2),
(3, 'c', 3),
(4, 'd', 4),
(5, 'e', 5),
(6, 'f', 6),
(7, 'g', 7),
(8, 'h', 8),
(9, 'i', 9),
(10, 'j', 10);
Initially, my procedure was returning with data as
SELECT ID, EmpName, Age FROM #mytable;
After processing the data, to the web page is sent as
[{1,"a",1},
{2,"b",2},
{3,"c",3},
{4,"d",4},
{5,"e",5},
{6,"f",6},
{7,"g",7},
{8,"h",8},
{9,"i",9},
{10,"j",10}]
If I use
SELECT ID, EmpName, Age
FROM #mytable
FOR JSON AUTO;
the result will be like
[{"ID":1,"EmpName":"a","Age":1},
{"ID":2,"EmpName":"b","Age":2},
{"ID":3,"EmpName":"c","Age":3},
{"ID":4,"EmpName":"d","Age":4},
{"ID":5,"EmpName":"e","Age":5},
{"ID":6,"EmpName":"f","Age":6},
{"ID":7,"EmpName":"g","Age":7},
{"ID":8,"EmpName":"h","Age":8},
{"ID":9,"EmpName":"i","Age":9},
{"ID":10,"EmpName":"j","Age":10}]
So what I need to get is the same response but without column name, as front-end lib uses the JSON array without keys.
SQL Server version 2012 is used.
I hope I am clear on my end. Thanks.
Try this:
SELECT STUFF
(
(
SELECT CONCAT(',{', ID, ', "', EmpName, '", ', age, '}')
FROM #mytable
FOR XML PATH(''), TYPE
).value('.', 'varchar(max)')
,1
,1
,'['
) + ']';
You could use the "select to a variable" trick to build the string.
declare #JsonesceString varchar(max);
select #JsonesceString = concat(#JsonesceString+','+char(10),'{',ID,',"',EmpName,'",',age,'}')
from #mytable
order by ID;
select concat('[',#JsonesceString,']') as Result;
Returns the value:
[{1,"a",1},
{2,"b",2},
{3,"c",3},
{4,"d",4},
{5,"e",5},
{6,"f",6},
{7,"g",7},
{8,"h",8},
{9,"i",9},
{10,"j",10}]

Compare BOM Quantity on the Same Table with SQL Server 2012

I am trying to get the comparison Bill of Materials between 2 products in the same table. I have a BOM Table
I would like to compare quantity from
PRODUCT A FROM ID=1 to PRODUCT CCC FROM ID=2
SUPPLIERPN are unique for (ID, PRODUCT) combination
The expected result
My question: How can I get the expected result with SQL?
My SQL Server syntax knowledge to basic queries so I have no idea how to do this. I tried to search but I do not know the correct term to describe this type of problem.
Normally, I solved this type of problem in the application site (loaded all the data from Database Server then did the comparison).
There is no (CCC, 555) so the expected output of that product is incorrect. Honestly, if you can't do this manually and get the correct output you have a much bigger problem. Moreover, posting images is a terrible TERRIBLE way to provide information.
But here is one interpretation that attempts to correct all of your errors. It only occurred to me after writing it that your pn is a string and not numeric - which is why the literals used to populate the table variable do not have quote marks.
set nocount on;
declare #x table (salesid tinyint, product varchar(3), supplierpn varchar(5), qty decimal(5,2));
insert #x (salesid, product, supplierpn, qty) values
(1, 'A', 1234, 1), (1, 'A', 555, 2), (1, 'A', 666, 3),
(1, 'BBB', 1234, 4), (1, 'BBB', 555, 5),
(2, 'CCC', 1234, 6), (2, 'CCC', 666, 7), (2, 'CCC', 777, 8), (2, 'CCC', 888, 9) ;
select * from #x order by salesid, product, qty;
with cte_a as (select supplierpn, qty from #x where salesid = 1 and product = 'A'),
cte_ccc as (select supplierpn, qty from #x where salesid = 2 and product = 'CCC')
select isnull(cte_a.supplierpn, cte_ccc.supplierpn) as supplierpn,
cte_a.qty as qty_a,
cte_ccc.qty as qty_ccc,
isnull(cte_ccc.qty, 0) - isnull(cte_a.qty, 0) as delta
from cte_a full join cte_ccc on cte_a.supplierpn = cte_ccc.supplierpn
order by supplierpn;

SQL Query by using with

I have the following query...
------ create table
create table test222
(
sid bigint,
scode nvarchar(50),
parentid bigint,
sname nvarchar(50)
)
insert into test222 values (1, '11', 0, 'iam a boy')
insert into test222 values (2, '111', 1, 'boy')
insert into test222 values (3, '1111', 1, 'bo')
insert into test222 values (4, '11111', 3, 'girl')
insert into test222 values (5, '111111', 0, 'boyy')
insert into test222 values (6, '1111111', 5, 'gril')
insert into test222 values (7, '22', 0, 'body')
insert into test222 values (8, '222', 7, 'girll')
following is my code,,,
;WITH SInfo AS
(
SELECT
t.sId,
t.scode,
t.ParentId,
t.sName,
CONVERT(nvarchar(800), t.scode) AS Hierarchy,
t.ParentId as HParentId
FROM test222 as t
WHERE
t.sname like '%bo%'
UNION ALL
SELECT
si.sId,
si.scode,
si.ParentId,
si.sName,
CONVERT(nvarchar(800), TH.scode + '\' + si.Hierarchy),
th.parentid
FROM SInfo as si
INNER JOIN test222 TH
ON TH.sId = si.HParentId
)
Select t.sId, t.scode, t.ParentId, t.sName, t.Hierarchy
from SInfo as t
where
HParentId = 0 and
not exists (select 1 from SInfo as s
where
s.sid <> t.sid and
s.Hierarchy like t.Hierarchy + '%')
the op generated is shown below
5 111111 0 boyy 111111
7 22 0 body 22
3 1111 1 bo 11\1111
the third row is not correct
It should be
3 111111 1 bo 11\111\1111.
How can i do that???
All you need to do is change the parent id of the record - sid=3 to its chronological parent instead of its grand parent :-) . Check below.
Change
insert into #test222 values (3, '1111', 1, 'bo')
to
insert into #test222 values (3, '1111', 2, 'bo')
The reason you are not seeing the middle portion (record - sid:2) is because record - sid=2 and record - sid=3 essentially share the same "FROM" criteria. sname= '%bo%' (or rather LIKE '%bo%') and parentid=1. The record - sid=3 is the last record in the set with this shared "FROM" criteria and hence is the record being returned.
Order of SQL query execution (FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY)
Here is a link to recursive CTE queries
Hope this helps.

Filtering a bottom up recursive CTE with Sql Server 2005

I'm trying to query a hierarchy of data in a single database table from the bottom up (I don't want to include parents that don't have a particular type of child due to authorities). The schema and sample data are as follows:
create table Users(
id int,
name varchar(100));
insert into Users values (1, 'Jill');
create table nodes(
id int,
name varchar(100),
parent int,
nodetype int);
insert into nodes values (1, 'A', 0, 1);
insert into nodes values (2, 'B', 0, 1);
insert into nodes values (3, 'C', 1, 1);
insert into nodes values (4, 'D', 3, 2);
insert into nodes values (5, 'E', 1, 1);
insert into nodes values (6, 'F', 5, 2);
insert into nodes values (7, 'G', 5, 2);
create table nodeAccess(
userid int,
nodeid int,
access int);
insert into nodeAccess values (1, 1, 1);
insert into nodeAccess values (1, 2, 1);
insert into nodeAccess values (1, 3, 1);
insert into nodeAccess values (1, 4, 1);
insert into nodeAccess values (1, 5, 1);
insert into nodeAccess values (1, 6, 0);
insert into nodeAccess values (1, 7, 1);
with Tree(id, name, nodetype, parent)
as
(
select n.id, n.name, n.nodetype, n.parent
from nodes as n
inner join nodeAccess as na on na.nodeid = n.id
where na.access =1 and na.userid=1 and n.nodetype=2
union all
select n.id, n.name, n.nodetype, n.parent
from nodes as n
inner join Tree as t on t.parent = n.id
inner join nodeAccess as na on na.nodeid = n.id
where na.access =1 and na.userid=1 and n.nodetype=1
)
select * from Tree
Yields:
id name nodetype parent
4 D 2 3
7 G 2 5
5 E 1 1
1 A 1 0
3 C 1 1
1 A 1 0
How can I not include the duplicates in the result set? The queries against the real tables have many more nodes at the lowest levels and hence many more duplicates of the parent nodes. The solution needs to work with at least SQL Server 2005.
Thanks in advance!
The simplest (not necessarily the most efficient) solution:
...
)
SELECT DISTINCT id,name,nodetype,parent FROM Tree;
This changes the order from your sample output because the DISTINCT operator implements a sort. If there is some intentional ordering there I cannot detect it but you can add an ORDER BY if you know the order you want.