Query response in JSON format without column name - sql

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}]

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?

SQL query cast from a group

I'm trying to make a query whit a 'cast group by' - output.
But not quit sure how to tackle this or even to start (I think i need cast and group by but not sure).
I have some code below which hopefully explains what I'm trying to do.
Could somebody help me to make a query to have the correct output?
CREATE TABLE buyers
(
id int,
buyer_name varchar(20)
);
INSERT INTO buyers
VALUES (1, 'harry'), (2, 'zoe'), (3, 'rose');
CREATE TABLE grocery
(
id int,
name VARCHAR(20),
id_buyers int
);
INSERT INTO grocery
VALUES (1, 'milk', 1), (2, 'milk', 1), (3, 'ham', 1), (4, 'bread', 2),
(5, 'bread', 2), (6, 'bread', 2), (6, 'milk', 2), (7, 'milk', 2),
(8, 'ham', 3);
CREATE TABLE wanted_output
(
name VARCHAR(20),
stuffed_lists VARCHAR(20)
);
INSERT INTO wanted_output
VALUES ('harry', '2x milk, 1x ham'), ('zoe', '3x bread, 2x milk'),
('rose', '1x ham ');
EDIT :
at this point I have this (not working):
SELECT
buyers.buyer_name,
COALESCE(
STUFF(
(SELECT ' , ' +
CAST( grocery.name AS varchar(max))
from grocery
where grocery.id_buyers = buyers.id
FOR XML PATH('')
), 1, 2, '' ),'')
AS wanted_output
FROM buyers
nvm afther some fideling :
SELECT
buyers.buyer_name,
COALESCE(
STUFF(
(SELECT ' , ' + cast(count(*) as varchar(4)) + ' x ' +
CAST( grocery.name AS varchar(max))
from grocery
where grocery.id_buyers = buyers.id
group by grocery.name
FOR XML PATH('')
), 1, 2, '' ),'')
AS wanted_output
FROM buyers

T-SQL how to filter by multiple criteria but prioritize what is returned?

I have the data below.
create table #results (
id int
, result_attr char(1)
, result varchar(100)
)
insert into
#results (id, result_attr, result)
values
(1, 'E', '***ERROR')
, (2, 'E', '***CORRECTED')
, (3, 'E', '***RESULTED')
, (4, 'E', '***AMENDED')
, (4, 'E', 'FOO')
, (5, 'E', 'ERROR***')
, (5, 'E', 'CORPOREAL')
, (6, 'E', '***CORRECTED')
, (7, 'E', '***RESULTED')
, (7, 'E', 'ABUNDANT')
, (7, 'E', 'PLENTITUDE')
, (8, 'E', 'INCORRECT')
, (9, 'A', 'HIGH')
, (10, 'A', 'LOW')
select *
from #results
drop table #results
The complete result set is:
My desired result set is:
This doesn't quite work:
select
res.id
, res.result_attr
, res.result
from #results as res
where
(charindex('***', res.result) > 0 or res.result_attr = 'E')
Tricky part being that I would want to exclude ID #4 with result "FOO" as well as ID #5 with result "CORPOREAL" and ID #7 with results "ABUNDANT" and "PLENTITUDE", but I want to keep ID #8 with result "INCORRECT". All in all, I want to exclude the following:
I've tried some windowing functions and other things, but am a bit stuck on this one. I would appreciate any assistance!
You can use row_number analytical function with conditional ordering as follows:
Select * from
(select
res.id
, res.result_attr
, res.result
, row_number() over (partition by res.id
order by case when charindex('***', res.result) > 0
then 1 else 2 end) as rn
from #results as res
where
(charindex('***', res.result) > 0 or res.result_attr = 'E') t
Where rn = 1
Order by id
Using:
select
res.id
, res.result_attr
, res.result
from results as res
where res.result LIKE '%***%' OR res.result = 'INCORRECT';
db<>fiddle demo

Many to many comparison in SQL Server

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.

Retrieving consecutive rows (and the counts) with the same values

I've got a table with almost 10 million views and would to run this query on the latest million or hundred thousand or so.
Here's a SQL fiddle with example data and input/output: http://sqlfiddle.com/#!9/340a41
Is this even possible?
CREATE TABLE object (`id` int, `name` varchar(7), `value` int);
INSERT INTO object (`id`, `name`, `value`)
VALUES
(1, 'a', 1),
(2, 'b', 2),
(3, 'c', 100),
(4, 'a', 1),
(5, 'b', 2),
(6, 'c', 200),
(7, 'a', 2),
(8, 'b', 2),
(9, 'c', 300),
(10, 'a', 2),
(11, 'b', 2),
(12, 'a', 2),
(13, 'b', 2),
(14, 'c', 400)
;
-- Want:
-- name, max(id), count(id)
-- 'a', 4, 2
-- 'b', 14, 5
-- 'a', 12, 3
If you want the latest and the id is implemented sequentially, then you can do this using limit or top. In SQL Server:
select top 100000 o.*
from object o
order by id desc;
In MySQL, you would use limit:
select o.*
from object o
order by id desc
limit 100000
select name, count(id) cnt, max(id) max_id, max(value) max_v
from
(select
top 1000000 -- MS SQL Server
id,name,value
from myTable
limit 1000000 --mySQL
order by id desc)
group by name
remove line which doesn't match your server.