t-sql compare trailing average with current data - tsql

I have a task to get the trailing average of the number of records received in
past 10 months and the number of records in this month. For example, in the set
of records below, the average of records per month for last three months is 4.33.
and the number of records of in this month is 3.
Hence the result expected is,
declare #recordsReceived table (id int, dob date)
INSERT #recordsReceived VALUES (1,'2020-01-01')
INSERT #recordsReceived VALUES (2,'2020-01-08')
INSERT #recordsReceived VALUES (3,'2020-01-17')
INSERT #recordsReceived VALUES (5,'2020-02-03')
INSERT #recordsReceived VALUES (6,'2020-02-09')
INSERT #recordsReceived VALUES (7,'2020-02-16')
INSERT #recordsReceived VALUES (8,'2020-02-21')
INSERT #recordsReceived VALUES (9,'2020-02-28')
INSERT #recordsReceived VALUES (10,'2020-03-01')
INSERT #recordsReceived VALUES (11,'2020-03-07')
INSERT #recordsReceived VALUES (12,'2020-03-21')
INSERT #recordsReceived VALUES (13,'2020-03-28')
INSERT #recordsReceived VALUES (14,'2020-04-03')
INSERT #recordsReceived VALUES (15,'2020-04-09')
INSERT #recordsReceived VALUES (16,'2020-04-30')
INSERT #recordsReceived VALUES (5,'2020-02-03')
INSERT #recordsReceived VALUES (6,'2020-02-09')
INSERT #recordsReceived VALUES (7,'2020-02-16')
INSERT #recordsReceived VALUES (8,'2020-02-21')
INSERT #recordsReceived VALUES (9,'2020-02-28')
INSERT #recordsReceived VALUES (10,'2020-03-01')
INSERT #recordsReceived VALUES (12,'2020-03-21')
INSERT #recordsReceived VALUES (12,'2020-03-21')
INSERT #recordsReceived VALUES (13,'2020-03-28')
INSERT #recordsReceived VALUES (14,'2020-04-03')
INSERT #recordsReceived VALUES (15,'2020-04-09')
INSERT #recordsReceived VALUES (16,'2020-04-30')

You can try this,
Select * From (
Select count(month(dob))*1.00/count(distinct(month(dob))) As [TAVG]
from #recordsReceived
Where month(dob) < (Select max(month(dob)) from #recordsReceived)) A
,
(Select count(month(dob)) [Current]
from #recordsReceived
Where month(dob) = (Select max(month(dob)) from #recordsReceived)) B

Related

How can I update TABLE1 rows when I change some TABLE2 rows in POSTGRESQL?

I am building a soccer management tool where the league's admin can update the score of every match in the MATCHES TABLE. At the same time I want to update the TEAMS TABLE columns.
For instance if the match is DALLAS vs PHOENIX, and the score was DALLAS 2 - PHOENIX 3, I want to update that match in the MATCH TABLE (I know how to tho this) but at the same time I want to update the points of those two teams based on the result we just updated.
Is there a way to do that in POSTGRESQL?
Thanks for your help.
You can do this for triggers. What is a Database trigger? A database trigger is a special stored procedure that is run when specific actions occur within a database. Most triggers are defined to run when changes are made to a table’s data. Triggers can be defined to run after (or before) INSERT, UPDATE, and DELETE table records. Triggers use two special database objects, INSERTED and DELETED, to access rows affected by the database actions.
When table record is inserted – Use the INSERTED table to determine which rows were added to the table.
When table record is deleted – Use the DELETED table to see which rows were removed from the table.
When table record is updated – Use the INSERTED table to inspect the new or updated values and the DELETED table to see the values prior to update.
In PostgreSQL INSERTED trigger object is called NEW and DELETED object is called OLD
For example:
We have two tables, user_group and user_detail. I would like to insert 12 records into table user_detail when inserting data to table user_group
CREATE TABLE examples.user_group (
id serial4 NOT NULL,
group_name varchar(200) NOT NULL,
user_id int4 NOT NULL
);
CREATE TABLE examples.user_detail (
id serial4 NOT NULL,
user_id int4 NOT NULL,
"month" int2 NOT NULL
);
-- create trigger function for inserting 12 records into user_detail table
CREATE OR REPLACE FUNCTION examples.f_user_group_after_insert()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
p_user_id integer;
begin
p_user_id := new.user_id; -- new is a system table (trigger objects), which return inserted new records for user_group tables
insert into examples.user_detail (user_id, month) values (p_user_id, 1);
insert into examples.user_detail (user_id, month) values (p_user_id, 2);
insert into examples.user_detail (user_id, month) values (p_user_id, 3);
insert into examples.user_detail (user_id, month) values (p_user_id, 4);
insert into examples.user_detail (user_id, month) values (p_user_id, 5);
insert into examples.user_detail (user_id, month) values (p_user_id, 6);
insert into examples.user_detail (user_id, month) values (p_user_id, 7);
insert into examples.user_detail (user_id, month) values (p_user_id, 8);
insert into examples.user_detail (user_id, month) values (p_user_id, 9);
insert into examples.user_detail (user_id, month) values (p_user_id, 10);
insert into examples.user_detail (user_id, month) values (p_user_id, 11);
insert into examples.user_detail (user_id, month) values (p_user_id, 12);
return new;
end;
$function$
;
-- join trigger function to user_group table, when will be run after insert
create trigger user_group_after_insert
after insert
on
examples.user_group for each row execute function examples.f_user_group_after_insert();

select columns in select query from another mapping table

I am looking for select query with dynamic column names that can be derived from another table. Below the sample data and query I am looking to get.
create table mapping_tmp (
string_number varchar,
mapping_name varchar
)
create table fact_tmp (
product varchar,
product_family varchar,
string1 varchar,
string2 varchar,
string3 varchar,
string4 varchar,
string5 varchar
)
insert into mapping_tmp values ('string1','commodity');
insert into mapping_tmp values ('string2','real commodity');
insert into mapping_tmp values ('string3','country');
insert into mapping_tmp values ('string4','region');
insert into mapping_tmp values ('string5','area');
insert into fact_tmp values ('P1','PF1','ABC1','DEF1','GHI1','JKL1','MNO1');
insert into fact_tmp values ('P2','PF2','ABC2','DEF2','GHI2','JKL2','MNO2');
insert into fact_tmp values ('P3','PF3','ABC3','DEF3','GHI3','JKL3','MNO3');
insert into fact_tmp values ('P4','PF4','ABC4','DEF4','GHI4','JKL4','MNO4');
insert into fact_tmp values ('P5','PF5','ABC5','DEF5','GHI5','JKL5','MNO5');
insert into fact_tmp values ('P6','PF6','ABC6','DEF6','GHI6','JKL6','MNO6');
Expected output, select fields should be taken from mapping_tmp and those fields data should be displayed in select result.
select product,
(select string_number from mapping_tmp where mapping_name = 'country') as country,
(select string_number from mapping_tmp where mapping_name = 'area') as area
from fact_tmp;
The actual query is
select product, string3 as country, string5 as area from fact_tmp;
and the output:
product country area
1 P1 GHI1 MNO1
2 P2 GHI2 MNO2
3 P3 GHI3 MNO3
4 P4 GHI4 MNO4
5 P5 GHI5 MNO5
6 P6 GHI6 MNO6
I am looking for simple sql query, I cannot use stored procedure or function in application.

Postgresql request to get recommended friends

I have two tables, friends and relations of friends:
Friendship is symmetrical.
CREATE TABLE t_users (
user_id varchar PRIMARY KEY,
name varchar
);
CREATE TABLE t_friendship (
friendship_id varchar PRIMARY KEY,
from_user_id varchar,
to_user_id varchar
);
INSERT INTO t_users VALUES ('us123', 'us123');
INSERT INTO t_users VALUES ('us456', 'us456');
INSERT INTO t_users VALUES ('us789', 'us789');
INSERT INTO t_users VALUES ('us987', 'us987');
INSERT INTO t_users VALUES ('us654', 'us654');
INSERT INTO t_users VALUES ('us321', 'us321');
INSERT INTO t_friendship VALUES ('fr123', 'us123', 'us456');
INSERT INTO t_friendship VALUES ('fr456', 'us123', 'us789');
INSERT INTO t_friendship VALUES ('fr789', 'us123', 'us987');
INSERT INTO t_friendship VALUES ('fr987', 'us456', 'us123');
INSERT INTO t_friendship VALUES ('fr654', 'us456', 'us321');
INSERT INTO t_friendship VALUES ('fr321', 'us987', 'us123');
INSERT INTO t_friendship VALUES ('fr322', 'us456', 'us654');
INSERT INTO t_friendship VALUES ('fr323', 'us654', 'us123');
INSERT INTO t_friendship VALUES ('fr324', 'us789', 'us654');
INSERT INTO t_friendship VALUES ('fr325', 'us321', 'us123');
How to make a request to get recommended friends.
For example friends of my friends.
Thank you.

Rem inserting in sqlplus?

In SQL Developer i am running this:
SPOOL C:\Export15.sql;
select /*insert*/* from Arithmisi ;
SPOOL OFF;
the outpout is this:
REM INSERTING into Arithmisi
SET DEFINE OFF;
Insert into "Arithmisi" (ARITHMOS) values ('3263');
Insert into "Arithmisi" (ARITHMOS) values ('3294');
Insert into "Arithmisi" (ARITHMOS) values ('3295');
Insert into "Arithmisi" (ARITHMOS) values ('3296');
Insert into "Arithmisi" (ARITHMOS) values ('3297');
Insert into "Arithmisi" (ARITHMOS) values ('3298');
Insert into "Arithmisi" (ARITHMOS) values ('3299');
Insert into "Arithmisi" (ARITHMOS) values ('3300');
Insert into "Arithmisi" (ARITHMOS) values ('3301');
Insert into "Arithmisi" (ARITHMOS) values ('3302');
Insert into "Arithmisi" (ARITHMOS) values ('3303');
Insert into "Arithmisi" (ARITHMOS) values ('3304');
Insert into "Arithmisi" (ARITHMOS) values ('3305');
Then i am running the same command in sql plus but the result is this:
ARITHMOS
3263
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
ARITHMOS
3304
3305
How can it been written in sql plus to produce the same output as SQL Developer?
It seems like alex helped with the final goal, but I will take a stab at answering the question you asked. You can get the inserts from sqlplus by forming the inserts as part of the select, but it is a bit tedious.
For one column table:
select 'insert into TABLE_NAME values ('''||FIELD_NAME||'''); ' from TABLE_NAME;
For multiple columns:
select 'insert into TABLE_NAME values ('''
||FIELD1_NAME||''','''
||FIELD2_NAME||''','''
||FIELD3_NAME||'''); '
from TABLE_NAME;
In your case:
SPOOL C:\Export15.sql;
select 'insert into Arithmisi values ('''||ARITHMOS||'''); ' from Arithmisi;
SPOOL OFF;
I hope this helps!

Rank data in TSQL

Data :
DECLARE #tblData TABLE (MediaID int,MediaTagName varchar(2000),MediaTypeName varchar(2000),keyitem varchar(2000),value varchar(2000))
INSERT INTO #tblData VALUES (48229,'Primary','Video','videoid','1234')
INSERT INTO #tblData VALUES (48229,'Primary','Video','src','somesrc')
INSERT INTO #tblData VALUES (48229,'Primary','Video','url','someurl')
INSERT INTO #tblData VALUES (48211,'Secondary','Video','videoid','1234')
INSERT INTO #tblData VALUES (48211,'Secondary','Video','src','somesrc')
INSERT INTO #tblData VALUES (48311,'Primary','Video','videoid','123456')
INSERT INTO #tblData VALUES (48311,'Primary','Video','src','somesrc')
INSERT INTO #tblData VALUES (48311,'Primary','Video','url','someurl')
Query tried :
SELECT
MediaID, MediaTagName,
RANK() OVER (PARTITION BY mediaid,mediatagname ORDER BY mediatagname) as rnk
FROM
#tblData
I need to get data that is partitioned based on MediaId and MedisTagName. essentially the end result should be :
DECLARE #tblDataExpected TABLE (MediaID int,MediaTagName varchar(2000),MediaTypeName varchar(2000),keyitem varchar(2000),value varchar(2000),rnk int)
INSERT INTO #tblDataExpected VALUES (48229,'Primary','Video','videoid','1234','1')
INSERT INTO #tblDataExpected VALUES (48229,'Primary','Video','src','somesrc','1')
INSERT INTO #tblDataExpected VALUES (48229,'Primary','Video','url','someurl','1')
INSERT INTO #tblDataExpected VALUES (48211,'Secondary','Video','videoid','1234','1')
INSERT INTO #tblDataExpected VALUES (48211,'Secondary','Video','src','somesrc','1')
INSERT INTO #tblDataExpected VALUES (48311,'Primary','Video','videoid','123456','2')
INSERT INTO #tblDataExpected VALUES (48311,'Primary','Video','src','somesrc','2')
INSERT INTO #tblDataExpected VALUES (48311,'Primary','Video','url','someurl','2')
SELECT * from #tblDataExpected
order by MediaID
Summary - The partition should be based off of mediatag and media id to generate the rank, however if there is a repeating mediaTag (for example "Primary") with a different media id, it should do an increment of the last rank it used for the primary with previous media ID and so on.
Firstly, you need to use DENSE_RANK instead of RANK as you have duplicates in your partitions. This will only increase the rank number on distinct rows.
Secondly, the partition only needs to be on MediaTagName as you are wanting to increment for every distinct MediaID for each MediaTagName. Therefore MediaID moves to the ORDER BY criteria.
I believe the following produces the results you are after:
SELECT td.MediaID,
td.MediaTagName,
td.MediaTypeName,
td.keyitem,
td.value,
DENSE_RANK() OVER (PARTITION BY MediaTagName ORDER BY MediaID) AS rnk
FROM #tblData AS td
ORDER BY td.MediaID;