Concat query result with equals values into one row - sql

I have the following query result:
Id
FKId
Count1
Count2
CountAll
Name
OriginalName
1
100
1
0
1
Food
Some value
1
101
0
1
1
Drink
Some value
1
102
1
0
1
Drink
Some value
What I want to do is to return all the FKId with same Name value into one row, something like this:
Id
FKId
Count1
Count2
CountAll
Name
OriginalName
1
100
1
0
1
Food
Some value
1
101, 102
1
1
2
Drink
Some value
At the moment this is the query that returns the 3 rows:
SELECT
t1.Id, t2.FkId,
COUNT(some case when here) [Count1],
COUNT(some case when here) [Count2],
COUNT(t2.FkId) [CountAll],
t3.Name, t3.OriginalName
FROM
table1 t1
JOIN
table2 t2 ON t1.Id = t2.Id
JOIN
table3 t3 ON t2.FKId = t3.FkId
GROUP BY
t1.Id, td.FkId, t3.Name, t3.OriginalName
I tried adding this to my current query:
DECLARE #Ids VARCHAR(8000)
(SELECT #Ids= COALESCE(#Ids+ ', ', '') + t2.FkId),
But I'm getting an error
Incorrect syntax near '='

You want to use STRING_AGG function.... something like
SELECT STRING_AGG(t2.FkId, ', ') as ID_LIST
Here is the MS documentation on it:
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-ver16

Related

Find the 2nd row of data based on a column value, if not available then print NULL

I am working on some project in hive and below problem is one part of it. Please note that i am going to apply the solution for this query on a subquery result /table which i have already made.
So as part of this, i am trying to print the row for each id based on column value of rnum. If rnum=2 then print both the column values, i.e., id,value. If rnum= 2 is not present for an id then then print id,'No value'.
Give below sample input and expected output.
For eg.
for id 100, since rnum is only 1, hence print value as 'No value'
for id 200, print only value for rnum=2, i.e., xyz and ignore value for rnum=1,3 and 4
Input:
id value rnum
100 abc 1
200 def 1
200 xyz 2
200 rtz 3
200 tgv 4
Expected output:
id value
100 No Value
200 xyz
You can use aggregation and case logic:
select id,
(case when sum(case when mum = 2 then 1 else 0 end) > 0
then max(case when mum = 2 then value end)
else 'No Value'
end)
from t
group by id;
You can do it as shown below:
select a.id, case when t.id is null then 'No value' else t.value end
from (select distinct id as id from t) a
left join t on t.rnum = 2 and a.id = t.id
Here's your query.
select t1.id, case when t2.rnum != 1 then t2.value else 'no value' end
from (
select count(1) as ct, id from test2
group by id) t1
left join test2 t2 on t2.id = t1.id and t2.rnum = 2
order by t1.id asc
Changed, allowing for any id values:
with t2(id, cnt) as
(
select id, count(*) as cnt
from t1
group by id
)
select t1.id,
max(case
when t2.cnt = 1 and t1.rnum = 1 then 'No Value'
when t2.cnt > 1 and t1.rnum = 2 then value
end)
from t1
join t2 on t2.id = t1.id
group by t1.id

Return id when id value does not equal 0 at least once

I have 2 tables.
table_1
id | product
1 | a
2 | b
3 | c
4 | d
table_2
product_id | value
1 | 0
2 | 0
1 | 5
2 | 0
4 | 10
How can I return details from table_1 for ids that:
- are present in table_2 (table_1.id = table_2.product_id)
- do not have any associated value equal to 0 (for example id "1" should be excluded)
The correct result would be id "4" as none of its values equal to zero.
I have tried below query but it returns also id "3" that is not present in the table_2.
SELECT * FROM table_1
WHERE id NOT IN (
SELECT product_id FROM table_2
WHERE value = 0)
You can use two conditions:
SELECT t1.*
FROM table_1 t1
WHERE EXISTS (SELECT 1
FROM table_2 t2
WHERE t1.id = t2.product_id
) AND
NOT EXISTS (SELECT 1
FROM table_2 t2
WHERE t1.id = t2.product_id AND t2.value = 0
);
The naive approach:
-- Step 1: Select product IDs to ignore
SELECT product_id
FROM table_2
WHERE value = 0
-- Step 2: Select product IDs to include
SELECT product_id
FROM table_2
WHERE product_id NOT IN ( -- Use the result of Step 1
SELECT product_id
FROM table_2
WHERE value = 0
)
-- Final query: Select products
SELECT *
FROM table_1
WHERE product_id IN ( -- Use the result of Step 2
SELECT product_id
FROM table_2
WHERE product_id NOT IN ( -- Use the result of Step 1
SELECT product_id
FROM table_2
WHERE value = 0
)
)
One option, using aggregation:
SELECT
t1.id,
t1.product
FROM table_1 t1
INNER JOIN table_2 t2
ON t1.id = t2.product_id
GROUP BY
t1.id,
t1.product
HAVING
COUNT(CASE WHEN t2.value = 0 THEN 1 END) = 0;
In order for the HAVING clause to return true, the product must not have had any zero value in the second table. Also, the inner join filters off any product which does not appear at all in the second table.
You can get the ids you need to use for the IN clause, by grouping by product_id and putting the condition in the HAVING clause:
SELECT * FROM table_1
WHERE id IN (
SELECT product_id
FROM table_2
GROUP BY product_id
HAVING SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END) = 0
)

TSQL - Select rows with same column A but different column B

I'm trying to find rows (Name) that does not have ID = 1. For example, if my table looked like this:
Name ID
--------------
A 1
A 0
B 1
B 0
C 0
D 2
D 0
The answer to this query would be:
Name
-----
C
D
Do you have any idea?
SELECT Name
FROM myTable
GROUP BY Name
HAVING SUM(CASE WHEN ID = 1 THEN 1 ELSE 0 END) = 0
Here is one way to do it:
SELECT DISTINCT Name
FROM Table t0
WHERE NOT EXISTS
(
SELECT 1
FROM Table t1
WHERE t0.Name = t1.Name
AND t1.Id = 1
)
Try this query:
SELECT DISTINCT(name)
FROM tbl t1
WHERE
NOT EXISTS (SELECT name FROM tbl t2 WHERE ID=1 AND t1.name=t2.name)
Select Distinct name
From myTable
Where name not in (Select name From myTable Where id= 1)

Union three tables and show where data came from

have no idea how to solve following:
There are three tables each with a column of names, for example
Table 1 - column name 'Name' - values 'A', 'B' and 'C'
Table 2 - column name 'Name' - values 'A' and 'B'
Table 3 - column nane 'Name' - values 'A' and 'C'
The goal is to UNION the tables - each value of the three tables should be shown only one time. In addition there should be three new "virtual columns" showing in which table the value is included('1' when value is included, '0' if not). So the result should look like this:
Value | Table1 | Table2 | Table3
--------------------------------
A | 1 | 1 | 1
B | 1 | 1 | 0
C | 1 | 0 | 1
Hope someone can help me, thanks in advance.
Does this do what you want?
select Name, max(Table1) as Table1, max(Table2) as Table2, max(Table3) as Table3
from (select Name, 1 as Table1, 0 as Table2, 0 as Table3
from table1
union all
select Name, 0 as Table1, 1 as Table2, 0 as Table3
from table2
union all
select Name, 0 as Table1, 0 as Table2, 1 as Table3
from table3
) t
group by Name;
You might want to use sum() instead of max() to get the number of times the value occurs in each table.
If your db supports full joins you can try the query below.
select
coalesce(t1.Name,t2.Name,t3.Name) myValue,
(case when max(t1.Name) is not null then 1 else 0 end) c1,
(case when max(t2.Name) is not null then 1 else 0 end) c2,
(case when max(t3.Name) is not null then 1 else 0 end) c3
from
Table1 t1
full join Table2 t2 on t1.Name = t2.Name
full join Table3 t3 on t1.Name = t3.Name
group by coalesce(t1.Name,t2.Name,t3.Name)
If you know that a value will not appear more than once in each table, you can remove the group by and max parts.
Here's my attempt (update: works f.e. in SQL-Server 2005 and upwards due to the CTE):
With names AS
(
SELECT Name, Source = 'T1'
FROM dbo.Table1
UNION ALL
SELECT Name, Source = 'T2'
FROM dbo.Table2
UNION ALL
SELECT Name, Source = 'T3'
FROM dbo.Table3
)
SELECT n.Name,
Table1 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T1' AND n2.Name=n.Name)
THEN 1 ELSE 0 END,
Table2 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T2' AND n2.Name=n.Name)
THEN 1 ELSE 0 END,
Table3 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T3' AND n2.Name=n.Name)
THEN 1 ELSE 0 END
FROM names n
GROUP BY n.Name
Demo

sql Query to get active Columnnames of table

I'm working with sql server 2008.I have 2 tables table1 contains,
id name chk1 chk2 chk3
1 aaa 0 0 1
2 bbb 2 2 1
3 ccc 1 0 2
table2 contains
chk_code chk_name flag
CH1 chk1 1
CH2 chk2 0
CH3 chk3 1
i want to get the result set like,
Column_Name
id
name
chk1
chk3
the check having flag value 0 doesnot appear in the resultset?
Use this query:
with x as (
select *
from sys.columns c
left join table2 t2 on c.name = t2.chk_name
where c.object_id = object_id('table1')
)
select name
from x
where flag = 1 or flag is null
You can achieve that using unpivot... But problem with unpivot is all unpivoted column name must be of same data type that to same size... if that is okay then you can use unpivot like this
SELECT Column_Name
FROM (SELECT *
FROM
(SELECT TOP 1 * FROM
tab1) p
UNPIVOT
(tab1 FOR Column_Name IN
([id], [name], [chk1], [chk2], [chk3])
)AS unpvt) AS vv WHERE Column_Name NOT IN
(SELECT chk_name FROM tab2 WHERE flag = 0)
SQLFiddle of above