Update count of union - sql

I have this query which is throwing a compilation error at the last ')'. The intellisense says 'Expected AS, ID or QUOTED_ID'.
What I am trying to do is - find the distinct values from the union of a table select and a function select, then get the count and update the column of another table with that value.
UPDATE #referees
SET [TotalKeywordCount] = (select count(*)
from (select Keyword
from [dbo].[RefereeFinderPersonKeyWord] P
where P.p_id=#referees.p_id
union
SELECT ltrim(rtrim(replace(Data, '''', '')))
from [SplitOne] (#keywords, ',')))
Any idea what I am doing wrong?

You need to add a name to the nested query that you use in the FROM of the query that pulls out the value for [TotalKeywordCount]. Below you have the code that assigns to it the name subquery:
UPDATE #referees
SET [TotalKeywordCount] = (select count(*) from (
select Keyword from [dbo].[RefereeFinderPersonKeyWord] P where P.p_id=#referees.p_id
union
SELECT ltrim(rtrim(replace(Data, '''', ''))) from [SplitOne] (#keywords, ',')) subquery )

Related

SQL Server 2016 - Transpose column of integers to row by day

I need to transpose one of the columns in the data date to a row of string and group by 2 other columns. My sample data consists of the following data:
I need the result to look like this:
That is all the LNs in one row per Employee code, per day.
I tried the below code -
DECLARE #Process_Conditions_Loans VARCHAR(500)
SELECT
t1.EmplCode,
t1.LogDate,
#Process_Conditions_Loans = CONCAT(COALESCE(#Process_Conditions_Loans + ',', ''),PS2)
FROM
#temp t1
WHERE
LN IS NOT NULL
GROUP BY
EmplCode, LogDate
But I am getting an error
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
I can not use group_concat since I am using SQL Server 2016.
Any help would be great appreciated.
Thanks,
JH
You can use the older form of string aggregation:
select emplcode, logdate,
stuff( (select concat(', ', ln)
from t
where t.emplcode = el.emplcode and t.logdate = el.logdate
order by ln
for xml path ('')
), 1, 2, ''
)
from (select distinct emplcode, logdate
from t
) el

Show Zero if there is no record count - ORACLE SQL query

The below Oracle query gives if there are any different errors with error_message and Serial_num.
If there is ZERO or No Different error count instead of showing Blank/Null result. How can i see the output like this? I tried with NVL(error_message,0) and COALESCE (Sum(total),0) but not getting the desired output.
Expected output:
1 Different Errors: 0
Oracle SQL Query:
SELECT
1 as Index_Num,
CONCAT('Different Errors: ', error_message || '# ' || serial_num),
SUM(total)
FROM (
SELECT error_message, serial_num, COUNT(*) total
FROM Table1
WHERE error_message NOT LIKE '%INVALID%'
GROUP BY error_message, serial_num
)
GROUP BY error_message, serial_num
Create a CTE for the subquery and use UNION ALL with NOT EXISTS to cover the case that the CTE does not return any rows:
WITH cte AS (
SELECT error_message, serial_num, COUNT(*) total
FROM Table1
WHERE error_message NOT LIKE '%INVALID%'
GROUP BY error_message, serial_num
)
SELECT
1 as Index_Num,
CONCAT(
'Different Errors: ',
list_agg(error_message || '# ' || serial_num) within group (order by error_message)
),
SUM(total)
FROM cte
UNION ALL
SELECT 1, 'Different Errors: ', 0
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM cte)
D'oh! Looks like I took too long. Here's another option for posterity:
SELECT
1,
CONCAT(
'Different Errors: ',
CASE
WHEN src.error_message IS NULL THEN ''
ELSE src.error_message || ' # ' || src.serial_num
END
) Summary,
COALESCE(src.total, 0) AS total
FROM dual -- Get a seed row (in case there are no rows in error table)
LEFT JOIN (
SELECT error_message, serial_num, COUNT(*) total
FROM Table1
WHERE error_message NOT LIKE '%INVALID%'
GROUP BY error_message, serial_num
) src ON 0=0
SQL Fiddle
It is not exactly what you are asking for, but might prove useful. You can easily add a row with the total number of errors, using grouping sets:
SELECT 1 as Index_Num,
('Different Errors: ' || error_message || '# ' || serial_num),
COUNT(*) as total
FROM Table1
WHERE error_message NOT LIKE '%INVALID%'
GROUP BY GROUPING SETS ( (error_message, serial_num), () );
Alas, this produces the summary row even when there are errors. It occurs to me that you might find this useful.

Concatening in a specific order given by a number

I have a table like this:
I want to concatenate the Product name in the given Product_order by ID.
Therefore, I should get something like: CC-TC-CA for ID 1.
you can use string_agg()- it'll work sql server 2016+
select id, string_Agg(product,',') as pname
from tablename
group by id
OR you can use stuff()
SELECT id,
STUFF((SELECT ',' + product
FROM tablename AS T1
WHERE T1.id = T2.id
FOR XML PATH('')), 1, 1, '')
FROM tablename AS T2
GROUP BY id
If you can use a stored procedure instead of a single query the += operator can do what you're looking for.
DECLARE #Product_order VARCHAR(100) = '';
SELECT #Product_order += Product + '-' FROM [table] WHERE id = 1 ORDER BY Product_Order;
SELECT SUBSTRING(#Product_order, 0, LEN(#Product_order));
Update: I've learned that returning multiple rows and using in an assignment in the select clause is unsupported behavior in SQL Server.

How to avoid duplicates in the STRING_AGG function SQL Server

I was testing a query in SQL in which I need to concatenate values ​​in the form of a comma-separated list, and it works, I just have the problem of duplicate values.
This is the query:
SELECT t0.id_marcas AS CodMarca,
t0.nombremarcas AS NombreMarca,
t0.imagenmarcas,
(SELECT String_agg((t2.name), ', ')
FROM exlcartu_devcit.store_to_cuisine t1
INNER JOIN exlcartu_devcit.cuisine t2
ON t1.cuisine_id = t2.cuisine_id
WHERE store_id = (SELECT TOP 1 store_id
FROM exlcartu_devcit.store
WHERE id_marcas = t0.id_marcas
AND status = 1)) AS Descripcion,
t0.logo,
t0.imagen,
(SELECT TOP 1 preparing_time
FROM exlcartu_devcit.store
WHERE id_marcas = t0.id_marcas
AND status = 1) AS Tiempo,
t0.orden,
(SELECT TOP 1 Avg(minimum_amount)
FROM exlcartu_devcit.store_delivery_zone
WHERE id_marcas = t0.id_marcas) AS MontoMinimo
FROM exlcartu_devcit.[marcas] t0
I thought the solution could be just adding a DISTINCT to the query to avoid repeated values ​​in this way ...
(SELECT STRING_AGG(DISTINCT (t2.name), ', ') AS Descripcion
But apparently the STRING_AGG() function does not support it, any idea how to avoid repeated values?
Simplest way is just select from select, like this:
with dups as (select 1 as one union all select 1 as one)
select string_agg(one, ', ') from (select distinct one from dups) q;
vs original
with dups as (select 1 as one union all select 1 as one)
select string_agg(one, ', ') from dups;

How to combine return results of query in one row

I have a table that save personnel code.
When I select from this table I get 3 rows result such as:
2129,3394,3508,3534
2129,3508
4056
I want when create select result combine in one row such as:
2129,3394,3508,3534,2129,3508,4056
or distinct value such as:
2129,3394,3508,3534,4056
You should ideally avoid storing CSV data at all in your tables. That being said, for your first result set we can try using STRING_AGG:
SELECT STRING_AGG(col, ',') AS output
FROM yourTable;
Your second requirement is more tricky, and we can try going through a table to remove duplicates:
WITH cte AS (
SELECT DISTINCT VALUE AS col
FROM yourTable t
CROSS APPLY STRING_SPLIT(t.col, ',')
)
SELECT STRING_AGG(col, ',') WITHIN GROUP (ORDER BY CAST(col AS INT)) AS output
FROM cte;
Demo
I solved this by using STUFF and FOR XML PATH:
SELECT
STUFF((SELECT ',' + US.remain_uncompleted
FROM Table_request US
WHERE exclusive = 0 AND reqact = 1 AND reqend = 0
FOR XML PATH('')), 1, 1, '')
Thank you Tim