Merge specific row in whole table - sql

I'm working on a web app, considering how to merge specific row in whole table.
Here is the example
Original data:
Name Date
-------------------
Jason Jul 2017
Tom Jun 2018
Andy Jun 2018
Mary Jun 2018
Alex Feb 2018
David Aug 2018
I'd like to make the same result into one big cell,like what we can do in Excel
Name Date
------------------
Jason Jul 2017
Tom
Andy Jun 2018
Mary
Alex Feb 2018
David Aug 2018
Is this possible in SQL Server? Or I need to do this change in the java or css layer

The exact output you want is something which is better handled in your presentation layer, e.g. using something like PHP, Java, etc. Perhaps the closest we might get to your output in SQL Server would be to do a group concatenation of the names by date, something like this:
SELECT
t1.Date,
STUFF((
SELECT ',' + t2.Name
FROM yourTable t2
WHERE t1.Date = t2.Date
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS Names
FROM (SELECT DISTINCT Date FROM yourTable) t1;
Demo

Related

SQL server multiple like query

I am trying to use multiple like query for column 1 and want show the data in seperate column, can I do
SELECT CONVERT(VARCHAR(100), DECRYPTBYKEY(ssr.optiontextresponse)) AS DueDate
FROM [dbo].[tblsubscribeReport] ssr
INNER JOIN [dbo].[tblsurveyque] sq on sq.surveyquestionid = CONVERT(VARCHAR(100), DECRYPTBYKEY(ssr.questionid)) --and [name] LIKE '%due%'
LEFT JOIN [dbo].[tblsurveyquestiono] so on so.surveyquestionoptionid = CONVERT(VARCHAR(100), DECRYPTBYKEY(ssr.optionid))
JOIN tblSubscribers s on s.SubscriberID = ssr.SubscriberId
WHERE
s.ClientID = '12'
and (sq.[name] LIKE '%due%' OR sq.[name] LIKE '%doc%' )
Due date
Feb 16, 2023
Shailesh Parihar
Feb 17 2023
Meet
Ank
feb 18 2023
Maria
Mar 2 2023
Mar 12 2023
Joun
Mar 11 2023
Smith
14/02/2023
Sarah
15-02-2023
Peggy
I Want show the my data in separate column

SQL: How to use subqueries to remove duplicates based on multiple conditions

First I want to remove duplicates by selecting the last date and then remove the remaining duplicates by selecting the role 'BLUE'
Example Table:
ID
STATUS
ROLE
DATE
1
ACTIVE
BLUE
Oct 20 2022
1
ACTIVE
RED
Dec 20 2022
2
ACTIVE
BLUE
Feb 02 2022
2
ACTIVE
RED
Feb 02 2022
3
INACTIVE
BLUE
Dec 03 2022
4
ACTIVE
RED
Dec 04 2022
Expected result:
ID
STATUS
ROLE
DATE
1
ACTIVE
RED
Dec 20 2022
2
ACTIVE
BLUE
Feb 02 2022
3
INACTIVE
BLUE
Dec 03 2022
4
ACTIVE
RED
Dec 04 2022
This is what I have so far:
SELECT a.ID,
a.STATUS,
a.ROLE,
a.DATE
FROM
(
SELECT ID, Max(DATE) as MaxDate
FROM WorkersTest
GROUP BY ID
) b
INNER JOIN WorkersTest as a
ON a.ID = b.ID
AND a.DATE = b.MaxDate
ORDER BY b."ID"
Then as you can see I still need to add the second filter/subquery...
First we can use following subquery to get each id with its latest date:
SELECT id, MAX(date) AS maxDate
FROM yourtable
GROUP BY id;
This can basically be used in the whole query like this:
SELECT y.id, y.status, y.role,
FORMAT(y.date, 'MMM dd yyyy') AS date
FROM yourtable y
JOIN
(SELECT id, MAX(date) AS maxDate
FROM yourtable
GROUP BY id) grouped
ON y.id = grouped.id
AND y.date = grouped.maxDate
ORDER BY y.id;
But this will list both "blue" and "red" role in case they both have the same latest date.
Therefore, the result would be incorrect:
ID
STATUS
ROLE
DATE
1
ACTIVE
RED
Dec 20 2022
2
ACTIVE
BLUE
Feb 02 2022
2
ACTIVE
RED
Feb 02 2022
3
INACTIVE
BLUE
Dec 03 2022
4
ACTIVE
RED
Dec 04 2022
So, to also satisfy the condition to only show the "blue" row in this case, there are different options. One of them would be to use a further subquery with a window function as for example ROW_NUMBER.
This could become necessary if there are further roles.
In our specific case with two roles only, we don't need this, but can use MIN instead because "blue" appears before "red" (if we would like to get "red" rows instead, we would use MAX).
So the query is now this one:
SELECT y.id, y.status,
MIN(y.role) AS role,
FORMAT(y.date, 'MMM dd yyyy') AS date
FROM yourtable y
JOIN
(SELECT id, MAX(date) AS maxDate
FROM yourtable
GROUP BY id) grouped
ON y.id = grouped.id
AND y.date = grouped.maxDate
GROUP BY y.id, y.status, y.date
ORDER BY y.id;
This will produce the correct result:
ID
STATUS
ROLE
DATE
1
ACTIVE
RED
Dec 20 2022
2
ACTIVE
BLUE
Feb 02 2022
3
INACTIVE
BLUE
Dec 03 2022
4
ACTIVE
RED
Dec 04 2022
We can replicate this here: db<>fiddle
A general hint: If possible, we should avoid to use SQL key words as column name or table name (here "role" and "date").
Especially the name "date" is also not meaningful because it misses to tell us which kind of date. We should therefore prefer clear names like for example "sellDate" or "quittingDate".

Getting calculated percentages within group using SQL

I have a dataset:
Date
June 2011
July 2011
Aug 2011
Sep 2011
Oct 2011
Jan 2012
Feb 2012
Mar 2012
Apr 2013
May 2013
that records down the date registered for each yearly project. (There are no project IDs however)
I would like to add in the additional variable Percentage, which represent the average progress made for that month. (For instance, if the project is registered for 4 months, then each month would progress incrementally by 25 %, (25,50,75,100)), specifically:
Percentage Date
20 June 2011
40 July 2011
60 Aug 2011
80 Sep 2011
100 Oct 2011
33 Jan 2012
66 Feb 2012
100 Mar 2012
50 Apr 2013
100 May 2013
However, my main problem would be that I am unable to know the starting month (period) and ending month (period) for each project for each year.
Are there any functions in SQL to create the calculated percentages in this case? I thought of creating a year variable and further using an indicator to indicate the start/end of the progress, but could not move on further.
Thank you again!
You can try this query.
Getting ROW_NUMBER() by year(dates) on subquery.
then get the percent.
SELECT (FLOOR(CAST(T2.RK AS decimal) * 100/(
SELECT COUNT(1) AS Totle
FROM T
WHERE year(dates) = T2.dates))) [Percentage],
T2.dates as [years],
T2.months as [months]
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY year(dates) ORDER BY dates DESC) AS RK,
year(dates) as dates,
month(dates) as months
FROM T
) AS T2
GROUP BY T2.dates,T2.RK,T2.months
Here is a simple Pseudo sql to get what you want . ?
select Year(date), Month(date) ,
(select sum(Progress_percentage) from dataset b where b.date <=a.date ) as
subquery_percentage
from dataset a
group by Year(date), Month(date)

SQL Top 1 in XML Path ('')

The following code:
select(
select m.Code + ' ' + cast(m.Completed as varchar(max)) + ' '+ cast(ol.Billed as varchar(max)) + ' ' + cast(m.Delete as varchar (max))
from matterdetails as m
full join officeledger as ol on ol.id=m.id
order by ol.Billed desc
for xml path(''))
returns the results
Code Completed Billed Deleted
-------- ----------- ----------- -----------
HK168/03 Mar 30 2012 Aug 17 2011 Mar 30 2012
HK168/03 Mar 30 2012 Feb 24 2011 Mar 30 2012
HK168/03 Mar 30 2012 Dec 23 2010 Mar 30 2012
FT080/03 Apr 4 2012 Mar 29 2012 Apr 4 2012
FT080/03 Apr 4 2012 Feb 9 2012 Apr 4 2012
FT080/03 Apr 4 2012 Oct 20 2011 Apr 4 2012
etc.
whereas i require the results
Code Completed Billed Deleted
-------- ----------- ----------- -----------
HK168/03 Mar 30 2012 Aug 17 2011 Mar 30 2012
FT080/03 Apr 4 2012 Mar 29 2012 Apr 4 2012
etc.
I know that i have to insert a select top 1 somewhere to limit the ol.Billed results, but i am unsure where. Any advice would be great.
try this: It will join with the max Billed Date for each Id
select(
select m.Code + ' ' + cast(m.Completed as varchar(max)) + ' '+ cast(ol.Billed as varchar(max)) + ' ' + cast(m.Delete as varchar (max))
matterdetails as m
full join (select id, Max(billed) as 'Billed' from officeledger) as ol on ol.id=m.id
order by ol.Billed desc
for xml path(''))
You could replace:
full join officeledger as ol on ol.id=m.id
with:
full join (select id,MIN(Billed) as Billed from officeledger group by id) as ol = ol.id = m.id
There should also be a way to do this with ROW_NUMBER(), but I won't write it unless you need it.

How to calculate the difference between values in two rows of one table using MS Access 2003 SQL? with EXTRA CRITERIA

Name ExactDate Presents
bob 2011 1
bob 2008 2
bob 2012 3
mary 1986 4
mary 2001 5
mary 2012 6
kate 2011 7
kate 2012 8
kate 2013 9
celia 2011 10
celia 1986 11
celia 1972 12
celia 2012 13
celia 1991 14
So the goal is we subtract the amount of presents kate got from celia on the same day and out put should be something like the following:
Name ExactDate Presents
celiaminuskate 2011 3
celiaminuskate 2012 5
Thank you so much I am a first time user of access and SQL . and have a data management task required of me at work. so this has really go me stuck
This is done in ms access 2003 SQL
HEY SO I GOT THE FIRST PART THERE AND NOW IT GETS HARDER ASSUMING THE DATA SET IS NOW LIKE THIS
Name ExactDate Presents Location
bob 2011 1 home
bob 2008 2 school
bob 2012 3 school
mary 1986 4 school
mary 2001 5 home
mary 2012 6 homw
kate 2011 7 home
kate 2012 8 home
kate 2011 9 school
celia 2011 10 school
celia 1986 11 school
celia 1972 12 home
celia 2012 14 home
celia 2012 13 school
So the goal is we subtract the amount of presents kate got from celia on the same year ( but since there are a few different present values for the same year we choose to have priority of home > school....for example celia and kate both recieves presents in 2012 but celia gets both home presents and school presents in 2012 in which case we choose her home present value to do the calculation) and out put should be something like the following:
Name ExactDate Presents
celiaminuskate 2011 3
celiaminuskate 2012 6
This should do it:
SELECT
'celiaminuskate' AS [NAME],
T1.[date] AS [EXACT DATE],
T1.presents - T2.presents AS [PRESENTS DIFF]
FROM
Some_Table T1
INNER JOIN Some_Table T2 ON
T2.[name] = 'kate' AND
T2.[date] = T1.[date]
WHERE
T1.[name] = 'celia'
ORDER BY
T1.[date]
A couple of suggestions since you're new to SQL:
Try to avoid using keywords, like "date" for column names
Your "date" column looks like a year, not a date. It should be named appropriately and you should make sure that it's the correct data type.
Since it sounds like the version of Access that you're using doesn't support the now standard JOIN syntax, here is another query which should be equivalent:
SELECT
'celiaminuskate' AS [NAME],
T1.[date] AS [EXACT DATE],
T1.presents - T2.presents AS [PRESENTS DIFF]
FROM
Some_Table T1, Some_Table T2
WHERE
T1.[name] = 'celia' AND
T2.[name] = 'kate' AND
T2.[date] = T1.[date]
ORDER BY
T1.[date]
T1 and T2 in this query are simply aliases for the tables in the FROM clause so that you can distinguish them.
If you're trying to put the results into another table then you will need this to be part of an INSERT statement. Or, with Access you might be able to use a query to generate a table as part of some wizard. I'm afraid that I don't have a copy handy to give more specifics. In any case, here is what the INSERT statement would look like:
INSERT INTO Some_New_Table (name, exactdate, presentsdiff)
SELECT ...
(The ellipsis just means to use the query as I have it up above)
You will need to do a self-join, because you are comparing rows from the same table.
Below we join table1 to itself using simular dates, but different names.
A more realistic answer would use unique row_ids instead of names.
Next we tell the database that we want only celia's rows in part1 and only kate's rows in part2.
SELECT 'celiaminuskate' AS useless_filler
, a.[date] AS whendidthishappen
, (celia.presents - kate.presents) AS outcome
FROM table1 AS kate
INNER JOIN table1 AS celia ON (a.[date] = b.[date] and a.name <> b.name)
WHERE celia.name = 'celia' and kate.name = 'kate'
Note that date is a reserved word and you will need to enclose it in square brackets []
The key to answering this is a self-join:
SELECT 'Celia - Kate' AS tag, C.ExactDate, C.Presents - K.Presents
FROM (SELECT ExactDate, Presents FROM AnonymousTable WHERE Name = 'celia') AS C
JOIN (SELECT ExactDate, Presents FROM AnonymousTable WHERE Name = 'kate') AS K
ON C.ExactDate = K.ExactDate
ORDER BY C.Date;
SELECT 'celiaminuskate', p1.exactdate, p1.presents - p2.presents
FROM presents p1 JOIN presents p2 ON p1.exactdate = p2.exactdate
WHERE p1.name = 'celia' AND p2.name = 'kate'