I have a table with a list of several different emails and Items. I'm trying to send out an email (whenever a button is pressed) to all of those emails with their Items, e.g.:
An email like this should be send when the button is pressed:
"Dear abc#mail.com, your cart is ready with item 1 and item 2."
I know how to send emails using Apex Items but I'm lost on how to do it with information inside a table.
Does anyone know how to do that?
Thanks!
This might be one option: create a procedure which runs when button is pressed; it reads table contents and "aggregates" list of items into message text.
As you already know how to send mail, I hope this is enough for you to make it work.
SQL> with test (user_email, item) as
2 -- sample data
3 (select 'abc#mail.com', 'item 1' from dual union all
4 select 'abc#mail.com', 'item 2' from dual union all
5 --
6 select '123#mail.com', 'item 1' from dual union all
7 select '123#mail.com', 'item 2' from dual union all
8 select '123#mail.com', 'item 3' from dual
9 )
10 -- code you might be interested in
11 select user_email,
12 'Dear ' || user_email ||', your cart is ready with ' ||
13 listagg(item, ', ') within group (order by item) as message_text
14 from test
15 group by user_email
16 /
USER_EMAIL MESSAGE_TEXT
------------ ----------------------------------------------------------------------
123#mail.com Dear 123#mail.com, your cart is ready with item 1, item 2, item 3
abc#mail.com Dear abc#mail.com, your cart is ready with item 1, item 2
SQL>
Related
I have a stored procedure which does following tasks on 2 tables related to each other as below
CREATE TABLE address (adr_id, ver_id, address) AS
SELECT 1, 1, 'newYork' FROM DUAL UNION ALL
SELECT 1, 2, 'newYork' FROM DUAL UNION ALL
SELECT 1, 3, 'newYork' FROM DUAL UNION ALL
SELECT 4, 1, 'Washington' FROM DUAL UNION ALL
SELECT 4, 2, 'Washington' FROM DUAL;
CREATE TABLE employee (emp_id,adr_id,ver_id,) AS
SELECT 100,1, 1 FROM DUAL UNION ALL
SELECT 200,1, 2 FROM DUAL UNION ALL
SELECT 300,1, 3 FROM DUAL UNION ALL
SELECT 400,4, 1 FROM DUAL UNION ALL
SELECT 500,4, 2 FROM DUAL;
Here Following tasks are done in stored procedure and required to be executed in parallel as to increase throughput on billions of records in both table
Note: Foreign key Constraints are relaxed
Find records with distinct address "newYork" and have them in cursor
Loop on Cursor record as follows
and process each address record select * from address where address ="newYork"
Insert a new record in Address table with same address as first record (with ver_id=0) in #3 and take the newly inserted id
Find parent table records based on foreign key in Employee table and update them with newly id mentioned in #4.
delete all records of #3
Since Step 2 to 6 can be executed in parallel just wanted to know how this can be achieved ?
Expected After
Address
adr_id
ver_id
address
11
0
newYork
12
0
Washington
Employee
id
adr_id
ver_id
100
11
1
200
11
2
300
11
3
400
12
1
500
12
2
As a frame challenge, do not update the adr_id and just change the version; that way you do not need to change the referential constraints.
MERGE INTO address dst
USING (
SELECT ROWID AS rid,
COUNT(*) OVER (PARTITION BY adr_id) AS cnt,
ROW_NUMBER() OVER (PARTITION BY adr_id ORDER BY ver_id) AS rn
FROM address
) src
ON (dst.ROWID = src.rid AND src.cnt > 1)
WHEN MATCHED THEN
UPDATE
SET ver_id = 0
DELETE WHERE src.rn > 1
fiddle
I have 2 tables and it is one to many relationship (parent & chdild). Its a dynamic table ,not a fixed data. More data can come in table.
user
Aid userName
1 author1
2 author2
3 author3
4 author4
etc
books
bid NAME Aid
1 x 1
2 y 1
3 z 2
4 z1 3
The Expected output is like below
'author1' AS author1,'x' AS x,'y' AS y,'author2' AS author2,'z' AS z,'author3' AS author3,'z1' AS z1
I have tried with parent table but how to get all row like in above format.
select listagg('''' || UserName || ''' as "' || UserName || '"', ',') within group (order by Aid)
from (select distinct Aid,UserName from user order by Aid);
Firstly, don't do this. If you want to pivot the data, do it in the third-party application (Java, C#, PHP, etc.) that you are using to access the database because that will support pivoting a data set rather than trying to force it through some dynamic SQL and trying to get a query to do something it is not intended to do.
However, if you really must (don't) then:
SELECT LISTAGG('''' || name || ''' AS ' || name, ',')
WITHIN GROUP (ORDER BY name) AS names
FROM (
SELECT username AS name
FROM "USER"
UNION
SELECT name
FROM books
)
Which, for the sample data:
CREATE TABLE "USER" (Aid, userName) AS
SELECT 1, 'author1' FROM DUAL UNION ALL
SELECT 2, 'author2' FROM DUAL UNION ALL
SELECT 3, 'author3' FROM DUAL UNION ALL
SELECT 4, 'author4' FROM DUAL;
CREATE TABLE books (bid, NAME, Aid) AS
SELECT 1, 'x', 1 FROM DUAL UNION ALL
SELECT 2, 'y', 1 FROM DUAL UNION ALL
SELECT 3, 'z', 2 FROM DUAL UNION ALL
SELECT 4, 'z1', 3 FROM DUAL;
Outputs:
NAMES
'author1' AS author1,'author2' AS author2,'author3' AS author3,'author4' AS author4,'x' AS x,'y' AS y,'z' AS z,'z1' AS z1
fiddle
I have data:
CLIENT_NO , DATE , TYPE
CLIENT 1- 22/09/2014 -001
CLIENT 1- 19/09/2014 -002
CLIENT 1- 10/09/2014 -005
CLIENT 2- 15/09/2014 -012
CLIENT 2- 20/09/2014 -011
I want to have latest TYPE stored in this table over time for each client. How can I do that using PL/SQL?
Well, you don't really need PL/SQL; pure SQL will do.
One option is to sort them (analytic functions as row_number or rank help in this case), and then fetch rows with row number = 1 (because of order by clause which sorts them by date value in descending order).
SQL> with
2 test (client_no, datum, type) as
3 -- sample data
4 (select 'client 1', date '2014-09-22', '001' from dual union all
5 select 'client 1', date '2014-09-19', '002' from dual union all
6 select 'client 1', date '2014-09-10', '005' from dual union all
7 select 'client 2', date '2014-09-15', '012' from dual union all
8 select 'client 2', date '2014-09-20', '011' from dual
9 ),
10 -- sort them
11 sorted as
12 (select client_no, datum, type,
13 row_number() over (partition by client_no order by datum desc) rn
14 from test
15 )
16 -- select the one with RN = 1
17 select client_no, datum, type
18 from sorted
19 where rn = 1;
CLIENT_NO DATUM TYPE
---------- ---------- ----
client 1 22/09/2014 001
client 2 20/09/2014 011
SQL>
Good day!
Folks, I have an issue when I want to compare multiple values.
For example I have the Log Data for today, 23rd April. This is related to yesterday's job(22nd April) with specific name.
In my comparison, I should select all logs with their job dates with this specific name. I say that logs' dates must be bigger than our job with this specific name. There are other jobs earlier done with this specific name.
How can I choose only the last nearest one?
Please could you advise?
For example:
Table: Job
id
name
job start date
Table: Log
id
type
Log date
We have 3 different jobs with name "Coding"
and 3 different logs.
Jobs:
1, coding, 21-Apr-10
2, coding, 21-Apr-14
3, coding, 21-Apr-18
Logs:
1. 1, error, 23-Apr-10
2. 2, error, 23-Apr-15
3. 3, error, 20-Apr-18
4. 4, error, 23-Apr-18
And there, when I want to execute logs and jobs, I must look to their dates. For example, error with id 1 is related to job with id 1, because log's date is bigger than job's date.
Or also, log with id 3 should be related to job with id 2.
Generally speaking, something like this might do the job:
select *
from some_table t
where t.date_column = (select max(t1.date_column)
from some_table t1
where t1.id = t.id
)
If it doesn't, please, provide test case (CREATE TABLE and INSERT INTO sample data, which would be the input), and - based on that, tell us what you expect as the output.
[EDIT]
This is somewhat strange data model; jobs and logs aren't related by anything but dates ... anyway, here's code that returns what you described (at least, how I understood it).
SQL> with tjob (id, name, job_start) as
2 (select 1, 'coding', to_date('21.04.2010', 'dd.mm.yyyy') from dual union
3 select 2, 'coding', to_date('21.04.2014', 'dd.mm.yyyy') from dual union
4 select 3, 'coding', to_date('21.04.2018', 'dd.mm.yyyy') from dual
5 ),
6 logs (id, type, log_date) as
7 (select 1, 'error', to_date('23.04.2010', 'dd.mm.yyyy') from dual union
8 select 2, 'error', to_date('23.04.2015', 'dd.mm.yyyy') from dual union
9 select 3, 'error', to_date('20.04.2018', 'dd.mm.yyyy') from dual union
10 select 4, 'error', to_date('23.04.2018', 'dd.mm.yyyy') from dual
11 )
12 select j.id job_id
13 from tjob j
14 where j.job_start = (select max(j1.job_start)
15 from tjob j1
16 where j1.job_start < (select l.log_date
17 from logs l
18 where l.id = &log_id));
Enter value for log_id: 1
JOB_ID
----------
1
SQL> /
Enter value for log_id: 3
JOB_ID
----------
2
SQL>
id text
1 hi
1 how are u
1 fine ?
2 rad
2 qey
3
I am searching for a query where it can let me insert id = 1 to another table in one column
id test
1 hi how are you fine ?
2 rad qey
with the listagg function , i will have such result : hi how are you fine ? .. can i have it such
hi
how are u
fine ?
This query can be used to achieve your result:
WITH tab(id,text) AS (
SELECT 1, 'hi' FROM dual UNION ALL
SELECT 1, 'how are u' FROM dual UNION ALL
SELECT 1, 'fine ?' FROM dual UNION ALL
SELECT 2, 'rad' FROM dual UNION ALL
SELECT 2, 'qey' FROM dual UNION ALL
SELECT 3, NULL FROM dual)
-----
--End of data
-----
SELECT ID,
listagg(text, ' ') within GROUP (ORDER BY ROWNUM) AS text
FROM tab
GROUP BY ID;
Output
ID TEXT
1 hi how are u fine ?
2 rad qey
3
But there is one problem, although order by rownum is used but you cannot guaranty the order of text, its better to have one more column in your table that can define the order of the text as below
id text order_text
1 hi 1
1 how are u 2
1 fine ? 3
2 rad 1
2 qey 2
3 1
and the use the query as
SELECT ID,
listagg(text, ' ') within GROUP (ORDER BY order_text) AS text
FROM tab
GROUP BY ID;
You can try the LISTAGG function.
For more information, see here.