Ordering contents of T-SQL STRING_AGG() [duplicate] - tsql

I have this query (I am using SQL Server 2019) and is working fine (combining Dates and Notes into one column). However, the result I am looking for is to have the latest date show up first.
How can I achieve that from this query?
SELECT ID,
​(SELECT string_agg(​concat(Date, ': ', Notes), CHAR(13) + CHAR(10) + CHAR(13) + CHAR (10)) as Expr1​
FROM(SELECT DISTINCT nd.Notes, nd.Date
FROM dbo.ReleaseTrackerNotes AS nd
INNER JOIN dbo.ReleaseTracker AS ac4 ON ac4.ID = nd.ReleaseTrackerID
WHERE (ac4.ID = ac.ID)) AS z_1) AS vNotes
FROM dbo.ReleaseTracker AS ac
GROUP BY ID
I have tried the ORDER BY but is not working
Here is my table:
CREATE TABLE [dbo].[ReleaseTrackerNotes](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ReleaseTrackerID] [int] NULL,
[AOC_ModelID] [int] NULL,
[Date] [date] NULL,
[Notes] [nvarchar](800) NULL,
CONSTRAINT [PK_ReleaseTrackerNotes] PRIMARY KEY CLUSTERED
CREATE TABLE [dbo].[ReleaseTracker](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AOC_ModelID] [int] NOT NULL,
[MotherboardID] [int] NOT NULL,
[StatusID] [int] NOT NULL,
[TestCateoryID] [int] NULL,
[TestTypeID] [int] NULL,
[DateStarted] [date] NULL,
[DateCompleted] [date] NULL,
[LCS#/ORS#] [nvarchar](20) NULL,
[ETCDate] [date] NULL,
[CardsNeeded] [nvarchar](2) NULL,
CONSTRAINT [PK_Compatibility] PRIMARY KEY CLUSTERED

Use WITHIN GROUP (ORDER BY ...):
SELECT
ID,
STRING_AGG(​TRY_CONVERT(varchar, Date, 101) + ': ' + Notes +
CHAR(13) + CHAR(10) + CHAR(13), CHAR(10))
WITHIN GROUP (ORDER BY Date DESC) AS Expr1​
FROM
(
SELECT DISTINCT ac4.ID, nd.Notes, nd.Date
FROM dbo.ReleaseTrackerNotes AS nd
INNER JOIN dbo.ReleaseTracker AS ac4
ON ac4.ID = nd.ReleaseTrackerID
) AS vNotes
GROUP BY ID;

Related

I can't create this PostgreSQL Query: Grouping by a different condition to the "order by" condition

I need to order my query in a different way i need to group my tables. I need to count how many men are in every department, but organize the query by quantity of people (Not only men, but also women) in every department, in descending way.
This is the diagram and the code of the tables:
Relational model of the tables
CREATE SCHEMA Academico;
CREATE TABLE Academico.PAIS(
ID int NOT NULL,
NOMBRE varchar(30) NOT NULL,
DESCRIPCION varchar(120) NULL,
CONSTRAINT PK_PAIS PRIMARY KEY (ID));
CREATE TABLE Academico.DEPARTAMENTO(
ID int NOT NULL,
NOMBRE varchar(30) NOT NULL,
CODIGO int NOT NULL,
DESCRIPCION varchar(120) NULL,
IDPAIS int NOT NULL,
CONSTRAINT PK_DEPARTAMENTO PRIMARY KEY (ID));
CREATE TABLE Academico.CIUDAD(
ID int NOT NULL,
NOMBRE varchar(255) NOT NULL,
CODIGO int NOT NULL,
DESCRIPCION varchar(120) NULL,
IDDEPARTAMENTO int NOT NULL,
CONSTRAINT PK_CIUDAD PRIMARY KEY (ID));
ALTER TABLE Academico.DEPARTAMENTO
ADD CONSTRAINT FK_DEPARTAMENTO_PAIS FOREIGN KEY(IDPAIS)
REFERENCES Academico.PAIS (ID)
on delete restrict on update restrict;
ALTER TABLE Academico.CIUDAD
ADD CONSTRAINT FK_CIUDAD_DEPARTAMENTO FOREIGN KEY(IDDEPARTAMENTO)
REFERENCES Academico.DEPARTAMENTO (ID)
on delete restrict on update restrict;
CREATE TABLE Academico.SEXO(
ID int NOT NULL,
NOMBRE varchar(30) NOT NULL,
DESCRIPCION varchar(120) NULL,
CONSTRAINT PK_SEXO PRIMARY KEY (ID));
CREATE TABLE Academico.TIPODOCUMENTO(
ID int NOT NULL,
NOMBRE varchar(30) NOT NULL,
DESCRIPCION varchar(120) NULL,
CONSTRAINT PK_TIPODOCUMENTO PRIMARY KEY (ID));
CREATE TABLE Academico.PERSONA(
ID int NOT NULL,
NOMBRE varchar(10) NOT NULL,
APELLIDO varchar(30) NOT NULL,
IDSEXO int NOT NULL REFERENCES Academico.SEXO(id),
IDCIUDAD int NOT NULL REFERENCES Academico.CIUDAD(id),
DOCUMENTO varchar(50) NOT NULL,
IDTIPODOCUMENTO int NOT NULL REFERENCES Academico.TIPODOCUMENTO(id),
FECHANACIMIENTO date NULL CHECK (FECHANACIMIENTO > '1900-01-01'),
FEvarcharEGISTRO date NOT NULL DEFAULT Now() ,
email varchar (355) UNIQUE NOT NULL,
PROFESION varchar(12) NULL,
PERFIL varchar(120) NULL,
CONSTRAINT PK_PERSONA PRIMARY KEY
(ID) );
I tried this two querys that give me the expected results but in a separated way:
select
d.nombre as _departamento, s.nombre as sex, count(1) as total_sexo
from
academico.persona p, academico.sexo s,
academico.ciudad c, academico.departamento d
where
p.idsexo = s.id
and p.idciudad = c.id
and c.iddepartamento = d.id
and upper( s.nombre ) = 'MASCULINO'
group by
d.id,
s.id
order by
d.nombre
-- =======================================================
-- I don't know how to "merge" these two into one query
-- =======================================================
select
d.nombre as _departamento, count(1) as total_gente
from
academico.persona p, academico.ciudad c,
academico.departamento d, academico.sexo s
where
p.idciudad = c.id
and c.iddepartamento = d.id
and p.idsexo = s.id
group by
d.id
order by
total_gente desc
;
I need to get those results with only one query
This is the perfect use for the FILTER (WHERE...) construct.
...
count(1) as total_gente,
count(1) filter (where upper( s.nombre ) = 'MASCULINO') as total_masculino
...
And then take the upper( s.nombre ) = 'MASCULINO' out of the main where clause.

Insert automatically large amount of records in postgresSQL table

i need to populate my table randomly with large amount of record in PostgresSQL like 200k
CREATE TABLE qr_code.tbl_transaction (
transaction_id varchar NOT NULL,
importo numeric NOT NULL,
alias varchar NOT NULL,
order_id varchar NOT NULL,
filiale varchar NOT NULL,
descrizione varchar NOT NULL,
data_creazione timestamp NOT NULL,
terminale varchar NOT NULL,
data_esecuzione timestamp NULL,
chiave_movimento_prenotata varchar NULL,
stato varchar NULL,
codice_fiscale varchar(16) NULL,
CONSTRAINT tbl_transaction_pk PRIMARY KEY (transaction_id)
);
How can i do this quickly?
You can use generate_series() to generate a lot of rows and use random() to generate random values.
Something like:
insert into tbl_transaction (transaction_id, importo, alias, order_id, filiale, descrizione, data_creazione, terminale, data_esecuzione, chiave_movimento_prenotata, stato, codice_fiscale)
select g.id::text,
random() * 1000,
'some alias',
(random()*10000 + 1)::text,
md5(random()::text),
md5(random()::text),
timestamp '2000-01-01' + make_interval(days => (random() * 7500 + 1)::int),
md5(random()::text),
timestamp '2000-01-01' + make_interval(days => (random() * 7500 + 1)::int),
md5(random()::text),
case (id % 5) + 1
when 1 then 'one'
when 2 then 'two'
when 3 then 'three'
when 4 then 'four'
when 5 then 'five'
else 'unknonw'
end,
'some_codice'
from generate_series(1,200000) as g(id);

Return values from left join only if it exists, otherwise from the main table

I have 2 tables
CREATE TABLE [dbo].[Owners]
(
[OwnerId] [int] NOT NULL,
[AccessToken] [nvarchar](50) NULL,
[TokenSecret] [nvarchar](50) NULL
)
CREATE TABLE [dbo].[Tweets]
(
[TweetId] [int] IDENTITY(1,1) NOT NULL,
[ReferenceId] [int] NULL,
[TweetContent] [nvarchar](max) NULL,
[ReferenceType] [int] NOT NULL,
[AccessToken] [nvarchar](50) NULL,
[TokenSecret] [nvarchar](50) NULL,
)
I would like to return all fields of tweets, and based on if there is an owners for the tweet, the AccessToken/TokenSecret will come from the owner table, if not then it will come from the tweets table.
I am having a hard time figuring out the best/efficient way to write this query.
This is what I have so far (only returns from main table, not owner if there is one)
SELECT *
FROM Tweets t
LEFT JOIN Owners o ON t.ReferenceId = o.OwnerId
WHERE t.ReferenceType = 1
I am using SQL Server 2017, in the tweet table, ReferenceId is the ownerid correspondence to he tweets table
Perhaps coalesce would be helpful to select the first non-null value:
select coalesce(o.AccessToken, t.AccessToken) as actualAccessToken [...]

T-SQL: Conversion failed when converting date and/or time from character string

Below is a trigger used to capture updates/inserts on an SQL table. I cannot figure out why, but whenever an update is done, I get the error message Conversion failed when converting date and/or time from character string. Here is the structure of the Transaction Log table:
CREATE TABLE [dbo].[TransactionLog](
[Id] [int] IDENTITY(1,1) NOT NULL,
[TransactionDate] [datetime] NOT NULL,
[Operator] [varchar](35) NOT NULL,
[TableName] [varchar](50) NOT NULL,
[Action] [char](1) NOT NULL,
[TableString] [nvarchar](255) NOT NULL,
[UserId] [char](6) NULL,
CONSTRAINT [PK_TransactionLog] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
Here is the table being updated:
CREATE TABLE [dbo].[AgentContEd](
[Id] [int] IDENTITY(1,1) NOT NULL,
[sNumber] [int] NOT NULL,
[StateCode] [char](3) NOT NULL,
[CourseCode] [char](6) NOT NULL,
[DateTaken] [date] NOT NULL,
[ExpirationDate] [date] NULL,
[CourseHours] [smallint] NOT NULL,
[Method] [varchar](15) NULL,
[LastChangeOperator] [char](8) NOT NULL,
[LastChangeDate] [datetime] NOT NULL,
[ControlId] [int] NULL,
CONSTRAINT [PK_AgentContEd] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
And here is the trigger that's causing the headache...
BEGIN
INSERT INTO dbo.TransactionLog
(
TransactionDate,
Operator,
TableName,
Action,
TableString,
UserId
)
SELECT
LastChangeDate,
'Op',
#tableName,
#action,
CAST(
'ID:' + CAST(ISNULL(Id, 'NULL') as char(4))
+ ' SymNum:' + CAST(ISNULL(sNumber, 'NULL') as char(10))
+ ' StateCode:' + ISNULL(StateCode, 'NULL')
+ ' DateTaken:' + CAST(ISNULL(DateTaken, 'NULL') as nvarchar(9))
+ ' ExpDate:' + CAST(ISNULL(ExpirationDate, 'NULL') as nvarchar(9))
+ ' CourseCode:' + ISNULL(CourseCode, 'NULL')
+ ' Hours:' + CAST(ISNULL(CourseHours, 'NULL') as char(3))
+ ' Mthd:' + ISNULL(Method, 'NULL')
As char(255)),
LastChangeOperator
FROM inserted
END
Try
+ ' DateTaken:' + ISNULL(CAST(DateTaken as varchar(9)), 'NULL')
+ ' ExpDate:' + ISNULL(CAST(ExpirationDate as varchar(9)), 'NULL')
I used varchar as it seems pointless to use nvarchar if you are going to be casting the string to char at the end anyway.
Also you probably need to use CONVERT with a style instead of CAST to store something useful. SELECT CAST(getdate() as nvarchar(9)) returns Sep 28 20 for me.
A list of formats is here

in T-SQL, is it possible to find names of columns containing NULL in a given row (without knowing all column names)?

Is it possible in T-SQL to write a proper query reflecting this pseudo-code:
SELECT {primary_key}, {column_name}
FROM {table}
WHERE {any column_name value} is NULL
i.e. without referencing each column-name explicitly.
Sounds simple enough but I've searched pretty extensively and found nothing.
You have to use dynamic sql to solve that problem. I have demonstrated how it could be done.
With this sql you can pick a table and check the row with id = 1 for columns being null and primary keys. I included a test table at the bottom of the script. Code will not display anything if there is not primary keys and no columns being null.
DECLARE #table_name VARCHAR(20)
DECLARE #chosencolumn VARCHAR(20)
DECLARE #sqlstring VARCHAR(MAX)
DECLARE #sqlstring2 varchar(100)
DECLARE #text VARCHAR(8000)
DECLARE #t TABLE (col1 VARCHAR(30), dummy INT)
SET #table_name = 'test_table' -- replace with your tablename if you want
SET #chosencolumn = 'ID=1' -- replace with criteria for selected row
SELECT #sqlstring = COALESCE(#sqlstring, '') + 'UNION ALL SELECT '',''''NULL '''' '' + '''+t1.column_name+''', 1000 ordinal_position FROM ['+#table_name+'] WHERE [' +t1.column_name+ '] is null and ' +#chosencolumn+ ' '
FROM INFORMATION_SCHEMA.COLUMNS t1
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE t2
ON t1.column_name = t2.column_name
AND t1.table_name = t2.table_name
AND t1.table_schema = t2.table_schema
WHERE t1.table_name = #table_name
AND t2.column_name is null
SET #sqlstring = stuff('UNION ALL SELECT '',''''PRIMARY KEY'''' ''+ column_name + '' '' col1, ordinal_position
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE table_name = ''' + #table_name+ '''' + #sqlstring, 1, 10, '') + 'order by 2'
INSERT #t
EXEC( #sqlstring)
SELECT #text = COALESCE(#text, '') + col1
FROM #t
SET #sqlstring2 ='select '+stuff(#text,1,1,'')
EXEC( #sqlstring2)
Result:
id host_id date col1
PRIMARY KEY PRIMARY KEY PRIMARY KEY NULL
Test table
CREATE TABLE [dbo].[test_table](
[id] int not null,
[host_id] [int] NOT NULL,
[date] [datetime] NOT NULL,
[col1] [varchar](20) NULL,
[col2] [varchar](20) NULL,
CONSTRAINT [PK_test_table] PRIMARY KEY CLUSTERED
(
[id] ASC,
[host_id] ASC,
[date] ASC
))
Test data
INSERT test_table VALUES (1, 1, getdate(), null, 'somevalue')