Show concatenated values in SQL Query - sql

I want to join my first sql query with table Types showed below by id_pr value.ID_PR values are repeated. I want to show all values from ident_st column concatenated with comma separator for same id_pr and rodz_st values. For example: Show all ident_st values for rodz_st='DZE' and id_pr=13.
first query:
SELECT NAME, NO FROM ORDERS o
LEFT JOIN TYPES t ON t.ID_ZM = o.ID_PR
table Orders:
ID ID_ZM NAME NO
---------- ---------- ------- --------
1 12 Dee 333
2 13 Rods 111
table Types:
ID ID_PR RODZ_ST IDENT_ST
---------- ---------- ------- --------
16 12 JEW 646101_1
10 12 JEW 236496_2
11 13 JEW 147301_5
15 13 DZE 259435_1
12 13 OBR 452171_3
13 13 OBR 286432_6
17 12 DZE 618054_1
19 13 DZE 182235_4
I want result like below:
NAME NO JEW DZE OBR
------- ----- ---------------- ------------------ -----------------
Dee 333 646101_1, 236496_2 618054_1
Rods 111 147301_5 259435_1, 182235_4 452171_3, 286432_6
Question: How to create sql join with concatenated statement to get showed result?

You may use list LISTAGG function with DECODE :
SELECT NAME, NO,
LISTAGG(DECODE(RODZ_ST,'JEW',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID DESC, RODZ_ST) AS JEWS,
LISTAGG(DECODE(RODZ_ST,'DZE',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID , RODZ_ST) AS DZE,
LISTAGG(DECODE(RODZ_ST,'OBR',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID , RODZ_ST) AS OBR
FROM ORDERS o
LEFT JOIN TYPES t ON t.ID_PR = o.ID_ZM
GROUP BY NAME, NO;
SQL Fiddle Demo

Related

How to grouping with distinct or group max sql

i have date like this Data
id name period difference
6172 A 6 10
6172 A 3 10
10099 AB 12 24
10099 AB 6 24
10099 AB 3 24
10052 ABC 12 26
10052 ABC 6 26
10052 ABC 3 26
9014 ABCD 12 21
9014 ABCD 6 21
9014 ABCD 3 21
how to get result like this
id name period difference
6172 A 6 10
10099 AB 12 24
10052 ABC 12 26
9014 ABCD 12 4
i try with distinct on (id), but the result like this
id name period difference
6172 A 6 10
10099 AB 6 24
10052 ABC 6 26
9014 ABCD 6 4
The query you want looks something like:
SELECT DISTINCT ON (id) *
FROM Data
ORDER BY id, period DESC;
Demo
This is probably the most efficient way to write your query on Postgres. Note that DISTINCT ON syntax does not support more than one column in the ON clause. The above logic happens to work here assuming that id would uniquely identify each group (that is, that id would always be unique). If not, then we might have to resort to using ROW_NUMBER with a partition over id and name.
using max()
select id, name, t2.period, difference from tableA t1
inner join
(select id, max(period) as period from tableA
group by id) t2 on t2.id = t1.id
using distinct()
select distinct id, name, t2.period, difference from tableA
it seems you need just max()
select id,name,max(period),max(difference)
from table group by id,name
Though i have not found difference=4 in your sample data but you used that on output,so i guessed its your typo
Use max()
select id, name, max(period), difference from tablename
group by id, name,difference
You can try my code:
SELECT
id, name, max(period), difference
FROM
data_table
group by id, name,difference
order by name
This is a demo link http://sqlfiddle.com/#!17/9ab8d/2

Retrieve max date for distinct IDs in a table [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
GROUP BY with MAX(DATE) [duplicate]
(6 answers)
Select First Row of Every Group in sql [duplicate]
(2 answers)
Oracle SQL query: Retrieve latest values per group based on time [duplicate]
(2 answers)
Return row with the max value of one column per group [duplicate]
(3 answers)
Closed 3 years ago.
I have the table ABC with the following data
Id Name Date Execution id
-- ---- --------- -------------
1 AA 09SEP2019 11
1 AA 08SEP2019 22
1 AA 07SEP2019 33
2 BB 09SEP2019 44
2 BB 08SEP2019 55
2 BB 07SEP2019 66
And I want to get for every distinct ID in the table its max date. So the result set must be as the following
Id Name Date Execution id
-- ---- --------- -------------
1 AA 09SEP2019 11
2 BB 09SEP2019 44
The query that returns the result I need
WITH MaxDate as (
SELECT Id,Name,Max(Date) from ABC group by Id,Name
)
SELECT view1.*, view2.exection_id
from
MaxDate view1,
ABC view2
WHERE
view1.date=view2.date and
view1.name=view2.name;
I don't like to get the max date for the distinct ID by this way. May be there is another way ? Might be there is more easiest way?
One way is to use RANK:
WITH cte AS (
SELECT ABC.*, RANK() OVER(PARTITION BY Id,Name ORDER BY Date DESC) rnk
FROM ABC
)
SELECT *
FROM cte
WHERE rnk = 1
ORDER BY id;
You can use keep dense_rank last do to this in one level of query, as long as you only want one or a small number of column retained:
select id,
name,
max(date_) as date_,
max(execution_id) keep (dense_rank last order by date_) as execution_id
from abc
group by id, name
order by id;
ID NAME DATE_ EXECUTION_ID
---------- ---- ---------- ------------
1 AA 2019-09-09 11
2 BB 2019-09-09 44
If ID and name are not always the same, and you want the name form the latest date too, then use the same pattern:
select id,
max(name) keep (dense_rank last order by date_) as name,
max(date_) as date_,
max(execution_id) keep (dense_rank last order by date_) as execution_id
from abc
group by id
order by id;
which gets the same result with your sample data.
With lots of columns it's probably simpler to use a subquery (CTE or inline view) with a ranking function and a filter (as #Lukasz shows).
With NOT EXISTS:
select t.* from ABC t
where not exists (
select 1 from ABC
where "Id" = t."Id" and "Name" = t."Name" and "Date" > t."Date"
)
I used and name = t.name only because you have it in your code.
If it is not needed you can remove it.
See the demo.
Results:
Id | Name | Date | Execution id
-: | :--- | :---------| -----------:
1 | AA | 09-SEP-19 | 11
2 | BB | 09-SEP-19 | 44

CTE - sum multiple rows with same id (with conditions)

I want to use SQL to sum multiple rows with same id when wk_days > 10
Sample data :
staff_id wk_days
--------------------
A 5
B 27
B 4
C 13
D 5
Output data :
staff_id wk_days
--------------------
A 5
B 31
C 13
D 5
the above output data is I want, I think I can use CTE to do it. How can it write this SQL Query?
No CTE needed, that is a simple group by query:
select staff_id, sum(wk_days) as wk_days
from the_table
group by staff_id
order by staff_id;
Online example: https://rextester.com/MBE21399

querying for multiple records by date

I've got few tables like this:
Color
id Color_Name
--- -------
1 RED
2 GREEN
Color_Shades
id ColorId ShadeId date_created
--- ------- ------- --------------
1 1 55 03/15/2013
2 1 43 02/01/2012
3 2 13 05/15/2011
4 2 15 06/11/2009
I'm trying to get a list of all distinct colors with their latest date.
I tried
SELECT a.Color_Name, b.date_created FROM Color a, Color_Shades b
WHERE a.id = b.ColorId
but this is giving me mixed results.
My desired results are:
Color_Name date_created
---------- ---------------
RED 03/15/2013
GREEN 05/15/2011
You are near to what you need. You just need to aggregate those columns using MAX to get theor latest date.
SELECT a.Color_name, MAX(b.date_created) date_created
FROM Color a
INNER JOIN Color_shades b
ON a.id = b.colorID
GROUP BY a.Color_Name
SQLFiddle Demo

Find N element in sequence using SQL

Given the following table:
Sequence Tag
----- ----
1 a
2 a
3 a
88 a
100 a
1 b
7 b
88 b
101 b
I would like a query that returns the 4th in each sequence of tags (ordered by Tag, Sequence asc):
Tag 4thInSequence
----- --------
a 88
b 101
What is the most efficient SQL I can use here? (Note: SQL Server 2008 tricks are allowed)
WITH Enumerated AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Tag ORDER BY Sequence) AS RN
FROM MyTable
)
SELECT * FROM Enumerated WHERE RN = 4;