GROUP_CONCAT in SQLite - sql

I am having data like this
1 A
1 B
1 C
1 D
2 E
2 F
3 G
3 H
3 I
3 J
3 K
by using this query
select ABSTRACTS_ITEM._id,Name
from ABSTRACTS_ITEM , ABSTRACT_AUTHOR , AUTHORS_ABSTRACT
where
ABSTRACTS_ITEM._id = AUTHORS_ABSTRACT.ABSTRACTSITEM_ID
and
ABSTRACT_AUTHOR._id = AUTHORS_ABSTRACT.ABSTRACTAUTHOR_ID
Now, I want to show data like this
1 A,B,C,D
2 EF
and so on..I also know it can achieve by GROUP_CONCAT function. So, I tried with this
SELECT ABSTRACTS_ITEM._id,
GROUP_CONCAT(ABSTRACT_AUTHOR.NAME) FROM
(select ABSTRACTS_ITEM._id,
Name
from
ABSTRACTS_ITEM , ABSTRACT_AUTHOR , AUTHORS_ABSTRACT
where
ABSTRACTS_ITEM._id = AUTHORS_ABSTRACT.ABSTRACTSITEM_ID
and
ABSTRACT_AUTHOR._id = AUTHORS_ABSTRACT.ABSTRACTAUTHOR_ID)
But, It shows me error. So, what I am doing wrong here. What are the right procedure to achieve that?

You need to add GROUP BY clause when you are using aggregate function. Also use JOIN to join tables.
So try this:
SELECT AI._id, GROUP_CONCAT(Name) AS GroupedName
FROM ABSTRACTS_ITEM AI
JOIN AUTHORS_ABSTRACT AAB ON AI.ID = AAB.ABSTRACTSITEM_ID
JOIN ABSTRACT_AUTHOR AAU ON AAU._id = AAB.ABSTRACTAUTHOR_ID
GROUP BY tbl._id;
See this sample SQLFiddle
What you were trying was almost correct. You just needed to add GROUP BY clause at the end. But the first one is better.
SELECT ID,
GROUP_CONCAT(NAME)
FROM
(select ABSTRACTS_ITEM._id AS ID,
Name
from
ABSTRACTS_ITEM , ABSTRACT_AUTHOR , AUTHORS_ABSTRACT
where
ABSTRACTS_ITEM._id = AUTHORS_ABSTRACT.ABSTRACTSITEM_ID
and
ABSTRACT_AUTHOR._id = AUTHORS_ABSTRACT.ABSTRACTAUTHOR_ID)
GROUP BY ID;

Here my answer to this closed question (it has a good showcase in it). SQL group results by row
You must add an Aggregate Function to your selected field.
The one you want is: GROUP_CONCAT
with a custom SEPARATOR ', '
See related MySQL Documentation:
https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html
Your Select Query would look like this:
SELECT id_place, placename, GROUP_CONCAT(plant_name SEPARATOR ', ') AS 'plantnames'
FROM BLOOM
JOIN PLACE ON id_place = fk_place
JOIN PLANT ON id_plant = fk_plant
GROUP BY id_place, placename;
Then you get your desired output:
id_place
placename
plantnames
1
New York
orchid, tulip
2
London
rosebush, orchid, tulip
3
Paris
rosebush, lily, violet
Here is a DB Fiddle to check this out (MySQL 8.0):
https://www.db-fiddle.com/f/sSU7G4kKEaxsLMNweAtLSA/2

Related

How to combine multiple rows with JSON PATH in SQL Server?

I have this dataset with 4 tables. I am trying to write the SQL query as following:
WITH test AS
(
SELECT
(f.name), f.id, f.domain, s.link,
(SELECT
name,
CASE
WHEN name IN (1, 3, 8) THEN 1
WHEN name IN (2, 6, 7) THEN 2
END AS [group]
FROM tags
WHERE corporate_statement_link_id = s.id
FOR JSON PATH) AS tags
FROM
fortune1000_companies f
LEFT JOIN
search_results s ON f.id = s.company_id
LEFT JOIN
corporate_statements c ON s.id = c.corporate_statement_link_id
WHERE
c.corporate_statement = 1
AND s.domain LIKE CONCAT('%', f.domain, '%')
)
SELECT name, link, tags
FROM test
but this produces the result where company names are duplicated because of the differences in link. For e.g., UnitedHeath Group (rows 4 & 5) is in two rows because the link is different. I want the result in such a way that the company name is shown just once, and tags are in the same group together. I don't need link to be shown; only included for this SO.
I think I figured it out.
This is what I did, and it gave me the answer I was looking for.
select name
, (STUFF((SELECT t.[name] from tags t
inner join search_results s
on s.id = t.corporate_statement_link_id
where f.id = s.company_id
FOR JSON PATH),1,2,'[{')) as ts
from [fortune1000_companies] f
where f.id between 1 and 101
I got the help from here

Display Summary Result in SQL Server

I have the following table structure also I have mention my expected output please help me with query as I don't know much about SQL query
Table 1 : Category
Name CatId
A 1
B 2
C 3
Table 2 : Emp Details
FName Id Dob CatId
Pratik 1 1958-04-06 2
Praveen 3 1972-05-12 1
Nilesh 2 1990-12-12 2
So far I have tried to get all result with:
SELECT A.Code,A.EmpName,A.DOB,B.cname
FROM EMPMASTER A
JOIN CATMASTER B ON A.cCode = B.ccode AND A.Compcode = B.CompCode
WHERE A.compcode = 'C0001' AND month(A.DOB) >= 1
AND MONTH(A.DOB) <= 12 AND A.termflag='L'
ORDER BY A.DOB
But my problem is, I also want summary results to be displayed
Expected Summary Output :
Grouping No Of Employees
A 1
B 2
C 0
I think you can use LEFT JOIN, GROUP BY and COUNT as follows:
SELECT [Grouping] = c.Name,
[No Of Employees] = COUNT(e.ID)
FROM Category AS c
LEFT JOIN EmpDetails AS e
ON e.CatId = c.CatId
GROUP BY c.Name;
TRY THIS:
SELECT A.NAME,
(SELECT COUNT(*) FROM #EMP B WHERE A.CATID = B.CATID) AS COUNT
FROM #TEMP A

How to combine columns in sql based on another field

I have a table in SQL Server 2008 R2 like this:
Acc_id Bench-1 Bench-2
-------------------------------
1 xx
1 vv
2 pp
2 ii
3 kk
4 ll
Now, I want to combine this table on the basis of Acc_id column and get something like:
Acc_id Bench-1 Bench-2
---------------------------------
1 xx vv
2 pp ii
3 kk
4 ll
So, could someone please help me out.
SELECT ISNULL(b1.Acc_id,b2.Acc_id) as Acc_id,
b1.data,
b2.data
FROM Bench-1 AS b1 FULL OUTER JOIN
Bench-2 AS b2 ON b2.Acc_id = b1.Acc_id
Check Below query
SELECT DISTINCT a.acc_id,
b.bench_1,
c.bench_2
FROM table1 a
LEFT OUTER JOIN (SELECT acc_id,
bench_1
FROM table1
WHERE Isnull(bench_1, '') <> '') b
ON a.acc_id = b.acc_id
LEFT OUTER JOIN (SELECT acc_id,
bench_2
FROM table1
WHERE Isnull(bench_2, '') <> '') c
ON a.acc_id = c.acc_id
I would do this like:
select
Acc_id,
max([Bench-1)] as [Bench-1],
max(([Bench-2]) as [Bench-2]
from
myTable
group by
Acc_id
This assumes Acc_id won't have multiple rows with data in the same columns
If that is the case then your knowledge of the use of the results will come into play. I often will perform this more completely like
select
Acc_id,
min([Bench-1)] as [Bench-1Min],
max([Bench-1)] as [Bench-1Max],
Count([Bench-1)] as [Bench-1Count],
min([Bench-2)] as [Bench-2Min],
max([Bench-2)] as [Bench-2Max],
Count([Bench-2)] as [Bench-2Count],
from
myTable
group by
Acc_id
All this depends on the actual complexity of the real data and what you want to do with the results. If it IS actually as simple as you example the multi-join solution may work for you, but I often find that in more complex summarizations the group by solution give me results and performance I need.

How to get first entry with a value from an hierarchical setting structure?

I have a couple of tables. One table with Groups:
[ID] - [ParentGroupID]
1 - NULL
2 1
3 1
4 2
And another with settings
[Setting] - [GroupId] - [Value]
Title 1 Hello
Title 2 World
Now I'd like to get "Hello" back if I'd query the Title for Group 3
And I'd like to get "World" back if I'd query the Title for Group 4 (And not "Hello" as well)
Is there any way to efficiently do this in MSSQL? At the moment I am resolving this recursively in code. But I was hoping that SQL could solve this problem for me.
Don't knoww the SQL Server syntax but something like the following?
SELECT settings.value
FROM settings
JOIN groups ON settings.groupid = groups.parentgroupid
WHERE settings.setting = 'Title'
AND groups.id = 3
This is a problem we've encountered multiple times in our company. This would work for any case, including when the settings can be set only at some levels and not others (see SQL Fiddle http://sqlfiddle.com/#!3/16af0/1/0 :
With GroupSettings(group_id, parent_group_id, value, current_level)
As
(
Select g.id as group_id, g.parent_id, s.value, 0 As current_Level
From Groups As g
Join Settings As s On s.group_id = g.id
Where g.parent_id Is Null
Union All
Select g.id, g.parent_id, Coalesce((Select value From Settings s Where s.group_id=g.id), gs.value), current_level+1
From GroupSettings as gs
Join Groups As g On g.parent_id = gs.group_id
)
Select *
From GroupSettings
Where group_id=4
I believe the following is what you are seeking. See the sqlfiddle
SELECT vALUE FROM
Groups g inner join Settings s
ON g.ParentGroupId = s.GroupID
WHERE g.ID = 3 -- will return Hello,], set ID = 4 will return World

How to exclude records with certain values in sql select

How do I only select the stores that don't have client 5?
StoreId ClientId
------- ---------
1 4
1 5
2 5
2 6
2 7
3 8
I'm trying something like this:
SELECT SC.StoreId FROM StoreClients
INNER JOIN StoreClients SC
ON StoreClients.StoreId = SC.StoreId
WHERE SC.ClientId = 5
GROUP BY StoreClients.StoreId
That seems to get me all the stores that have that client but I can't do the opposite because if I do <> 5 ill still get Store 1 and 2 which I don't want.
I'm basically trying to use this result in another query's EXISTS IN clause
One way:
SELECT DISTINCT sc.StoreId
FROM StoreClients sc
WHERE NOT EXISTS(
SELECT * FROM StoreClients sc2
WHERE sc2.StoreId = sc.StoreId AND sc2.ClientId = 5)
SELECT SC.StoreId
FROM StoreClients SC
WHERE SC.StoreId NOT IN (SELECT StoreId FROM StoreClients WHERE ClientId = 5)
In this way neither JOIN nor GROUP BY is necessary.
SELECT DISTINCT a.StoreID
FROM tableName a
LEFT JOIN tableName b
ON a.StoreID = b.StoreID AND b.ClientID = 5
WHERE b.StoreID IS NULL
SQLFiddle Demo
OUTPUT
╔═════════╗
║ STOREID ║
╠═════════╣
║ 3 ║
╚═════════╝
SELECT StoreId
FROM StoreClients
WHERE StoreId NOT IN (
SELECT StoreId
FROM StoreClients
Where ClientId=5
)
SQL Fiddle
You can use EXCEPT syntax, for example:
SELECT var FROM table1
EXCEPT
SELECT var FROM table2
<> will surely give you all values not equal to 5.
If you have more than one record in table it will give you all except 5.
If on the other hand you have only one, you will get surely one.
Give the table schema so that one can help you properly